Thursday, December 13, 2007

Embrace and Extend or Standardize and Stultify

The operator precedence in the title is correct: and binds tighter than or.

I've long been a fan of the GNU compiler (since at least the early 90s), but I'm a little disappointed with their current direction.

Let's say you wanted a C++ class for string handling. We'll just put in a char * member variable (the only data member) and some cool functions like Left, Capitalize, Parse and Rot13 (also known as SuperSecretEncryption).

class CString {
CString Left(int NumberCharacters);
void Capitalize();
int Parse(char *Format, ...);
void Rot13();
char *m_Data;

A cool thing to do with strings like this is to pass them to printf:

CString MyString;
printf("Here it is: <%s>\n", MyString);

Should this work? Consider:
char *foo; printf("%s", foo);

The arguments to printf are a pointer to a string, and a pointer to a string. Now, for the MyString printf, the first argument is still a pointer to a string. The second is an object, and what actually gets put on the argument list is the contents of the object, which is, you guessed it, a pointer to a string.

So it should work. And it does with Microsoft's Visual C++ compiler (which is where I happened to meet this idiom).

However, the GNU C++ compiler complains with this message:
cannot pass objects of non-POD type 'CString' through '...'

If you take a look at this thread in the GNU C++ compiler mailing list, you'll see that it is not supported, because it is not standard. Worse, the compiler, in pursuit of standardness, does not issue an error message, and instead emits code causing the program to abort.

That's right: they print a warning, and if you ignore the warning and run the program: CORE DUMP. A little unfriendly...

The Intel C++ compiler does better, it prints a warning but emits code to do the right thing.

While Microsoft is often guilty of Embrace and Extending common standards (such as HTML so that web pages only correctly display in Internet Explorer), in this case I don't think they've done anything wrong. The metaphor is very useful, and there is no benefit to forcing programmers to use the clumsier:
printf("%s", (char *)MyStringObject);

(assuming that there is a conversion operator for CStrings).

The GNU compiler group is guilty of an equally evil technique: let's call it "Standardize and Stultify". When I pointed out that the metaphor was useful, I received the terse reply:
> The class is a non POD.

Meaning basically "we're sticking to the standard, broken though it may be".

The Intel compiler got it right, but of course this would tie me to Intel and AMD platforms.