OpenFest 2006 - Share the Freedom

February 23, 2005

Slash this, baby!

Well, well. There was a thread on the freebsd-hackers mailing list that started a couple of days ago, and it looked like some kind of trivial C programmer's mistake. As the thread unwound, however, people started to suspect weird syntax problems. In the end, it turned out that it was just a C compiler that liked C89 syntax - the original C language standard ratified by the ANSI X3J11 committee - and choked on C++-style // comments. Okay - fine - good - just use C-style /* comments */, and end-of-story, right?

Well, it turns out that there's more. After a bit of discussion on C89 versus the newer C99 standard (again from the ANSI X3J11 committee), Dag-Erling Smoergrav hit the list with the following gem of a program, which can actually differentiate between the C dialect used by the compiler without any #ifdef conditional compilation:

#include <stdio.h>

int
main(void)
{
        int a, b, c;

        a = 10;
        b = 2;
        c = a //* oops! */
            -b;
        switch (c) {
	case 8:
                printf("C99 or C++\n");
		break;
	case -5:
                printf("C89\n");
		break;
	default:
		printf("can't happen\n");
		break;
	}
        return 0;
}

So how 'bout that, eh? :) See how it performs quite differently under a compiler that treats // as the start of a comment, and one that only treats /* as such and lets through the '/' character? :)

Score one more for Obfuscated C. "Kids, don't try this at home!" And as a former coworker used to say, when he saw me get that faraway look in my eye in the midst of a weird programming practices' discussion over a beer or five, "Hey! Don't try this at work, either!"

Posted by roam at February 23, 2005 12:49 AM

Comments

Hmm.. is C99 a strict subset of C89? Seems to me that pretty much every compiler I've tried in recent years plays well with C99, which makes it weird to hear stories like this of people still using compilers that are locked into C89.

Posted by: Ivan Tumanov at February 23, 2005 08:57 AM

Actually, it's the other way 'round - C89 is supposed to be pretty much a subset of C99 :) And that holds true for most of the features that C99 introduces, like variable definitions in the middle of a block instead of at the top, more data types (at long last standardizing long long int, and intmax_t being one of the greatest ideas IMHO), more printf() modifiers (say, %j for intmax_t), 'restrict' pointer qualifiers... All of those are things that would simply break a C89 compiler with invalid syntax (well, maybe except for the printf() modifier) so that the program would not even compile, never mind produce different resulsts. However, it turns out that some of the differences *do* allow for the compilation to proceed and generate different runtime behavior - and this sounds, erm, let's say just 'tricky', so we don't go hurling around words like 'bad' :)

There's a nice reference for the C99 features and extensions at IBM's Software information center; I'm not sure if the standards themselves are freely available.

Posted by: Peter Pentchev at February 23, 2005 11:20 PM

Hmm, something funny came up here and ate the URL - the IBM reference is at http://publib.boulder.ibm.com/infocenter/macxhelp/index.jsp?topic=/com.ibm.vacpp6m.doc/getstart/overview/apx_lang_support.htm

Posted by: Peter Pentchev at February 23, 2005 11:23 PM

*Oof!* Only I didn't really answer your question, did I now? :)

For various historical reasons, the system compiler in the FreeBSD 4.x base system is still GCC 2.95.x, which does not grok C99 all that well. For various POLA reasons, the system compiler in the FreeBSD 4.x-STABLE branch will never be updated/upgraded to GCC 3.x or some other C99 compiler.

Yes, this does lead to a bit of more work porting newer applications every now and then; still, that's the way it ought to be done.

Posted by: Peter Pentchev at February 25, 2005 09:01 AM
TrackBack