Tim_CDC_Roberts@cup.portal.com (10/20/89)
While attepting to test some of the entries in the Obfuscated C Contest, I find that Microsoft C 5.0 fails to compile constructs such as the following: #define d define #d a include #a <stdio.h> MSC complains that "d" is an unknown preprocessor directive and aborts. Does the standard require that this construct should compile correctly? I also encountered one occurrance of something like the following: #include <stdio.h> #define abcde getchar ... ch = abcde(); The preprocessor substituted 'getchar' for 'abcde', but then failed to expand the 'getchar()' macro from stdio. This resulted in an "Unresolved External: _getchar" at load time. Isn't the preprocessor legally and morally bound to recursively substitute macros, at least until a cycle is found? Tim_CDC_Roberts@cup.portal.com | I Survived The ...!sun!portal!cup.portal.com!tim_cdc_roberts | Great Quake of '89.
henry@utzoo.uucp (Henry Spencer) (10/22/89)
In article <23218@cup.portal.com> Tim_CDC_Roberts@cup.portal.com writes: > #define d define > #d a include > #a <stdio.h> > >MSC complains that "d" is an unknown preprocessor directive and aborts. >Does the standard require that this construct should compile correctly? Section 3.8.3 (Oct 1988 draft, roughly current except for wording changes): "If a # preprocessing token, followed by an identifier, occurs lexically at the point at which a preprocessing directive could begin, the identifier is not subject to macro replacement." In other words, ANSI C specifically says that it *doesn't* work. > #define abcde getchar > ... > ch = abcde(); > >The preprocessor substituted 'getchar' for 'abcde', but then failed to >expand the 'getchar()' macro from stdio... Unless I have missed some fine point, your preprocessor is wrong again. This is legal. It should be remembered that the preprocessor was *very* vaguely defined in the old days, and tricky fine points like this varied widely, indeed wildly, between implementations. ANSI C has nailed down most of it, but the macro-replacement section in the draft standard is easily one of the two or three trickiest parts of the whole document. (Indeed, there are still one or two small fuzzy areas that were overlooked.) It will be quite a while before all preprocessors comply exactly. -- A bit of tolerance is worth a | Henry Spencer at U of Toronto Zoology megabyte of flaming. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
gwyn@smoke.BRL.MIL (Doug Gwyn) (10/22/89)
In article <23218@cup.portal.com> Tim_CDC_Roberts@cup.portal.com writes: > #define d define > #d a include >Does the standard require that this construct should compile correctly? No, it requires that a diagnostic be issued. >Isn't the preprocessor legally and morally bound to recursively >substitute macros, at least until a cycle is found? Yes; I suspect in the case you reported the compiler failed to look beyond the replacement buffer for the () necessary for the getchar() expansion to be triggered. That's a bug.
davidsen@crdos1.crd.ge.COM (Wm E Davidsen Jr) (10/25/89)
In article <1989Oct21.233915.23217@utzoo.uucp>, henry@utzoo.uucp (Henry Spencer) writes: | Section 3.8.3 (Oct 1988 draft, roughly current except for wording changes): | | "If a # preprocessing token, followed by an identifier, occurs lexically | at the point at which a preprocessing directive could begin, the identifier | is not subject to macro replacement." | | In other words, ANSI C specifically says that it *doesn't* work. Another thing doesn't work, although it would be useful. If you have macros of the form: #define FOO 123 #define BAR FOO #define DEMO(c) printf("Demo:"#c"\n") then: DEMO(BAR); does not do a substitution of FOO for BAR, nor 123 for FOO. To make this work the value of the argument must be forced to be evaluated first. #define XDEMO(c) DEMO(c) and: XDEMO(BAR); now substitutes 123. This is how I would expect it to work, from the section you quote. Both gcc and a beta of MSC work just that way. Test prog for the terminally curious: #define FOO 123 #define BAR FOO #define X(c) printf("X:"#c"\n") #define TMP(c) X(c) X(FOO); X(BAR); TMP(BAR); -- bill davidsen (davidsen@crdos1.crd.GE.COM -or- uunet!crdgw1!crdos1!davidsen) "The world is filled with fools. They blindly follow their so-called 'reason' in the face of the church and common sense. Any fool can see that the world is flat!" - anon
johnsc@microsoft.UUCP (John Schwabacher) (10/25/89)
In article <1989Oct21.233915.23217@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: }In article <23218@cup.portal.com> Tim_CDC_Roberts@cup.portal.com writes: }> ... ["#define d define" example removed] }>MSC complains that "d" is an unknown preprocessor directive and aborts. }>Does the standard require that this construct should compile correctly? } ... [ANSI spec removed] }In other words, ANSI C specifically says that it *doesn't* work. } }> #define abcde getchar }> ... }> ch = abcde(); }> }>The preprocessor substituted 'getchar' for 'abcde', but then failed to }>expand the 'getchar()' macro from stdio... } }Unless I have missed some fine point, your preprocessor is wrong again. }This is legal. } Wait a minute. "Wrong again"? You just said MSC got the first one right. When I tried the "#define abcde getchar" using MSC 5.10, it worked fine. I don't have 5.0 handy, so I can't say about that. *None* of the Obscure C contest winners that I tried to build under Xenix worked correctly. Bummer.
henry@utzoo.uucp (Henry Spencer) (10/25/89)
In article <8189@microsoft.UUCP> johnsc@microsoft.UUCP (John Schwabacher) writes: >}Unless I have missed some fine point, your preprocessor is wrong again. >}This is legal. >} > >Wait a minute. "Wrong again"? You just said MSC got the first one right. As I recall, the original posting discussed two different compilers, one of which got the first one wrong too. I should have been clearer. -- A bit of tolerance is worth a | Henry Spencer at U of Toronto Zoology megabyte of flaming. | uunet!attcan!utzoo!henry henry@zoo.toronto.edu
seanf@sco.COM (Sean Fagan) (10/27/89)
In article <11374@smoke.BRL.MIL> gwyn@brl.arpa (Doug Gwyn) writes: >>Isn't the preprocessor legally and morally bound to recursively >>substitute macros, at least until a cycle is found? >Yes; I suspect in the case you reported the compiler failed to look >beyond the replacement buffer for the () necessary for the getchar() >expansion to be triggered. That's a bug. Which is fixed in MSC 5.1 (I believe). At least, it's fixed in our Latest and Greatest compilers for SCO *nix, which are based on MSC 5.1 currently. Horrible looking code is generated, though (C code, not the assembly). -- Sean Eric Fagan | "Time has little to do with infinity and jelly donuts." seanf@sco.COM | -- Thomas Magnum (Tom Selleck), _Magnum, P.I._ (408) 458-1422 | Any opinions expressed are my own, not my employers'.