Path: utzoo!attcan!uunet!lll-winken!ncis!helios.ee.lbl.gov!pasteur!ucbvax!decwrl!purdue!mailrus!tut.cis.ohio-state.edu!rutgers!cmcl2!adm!smoke!gwyn From: gwyn@smoke.BRL.MIL (Doug Gwyn ) Newsgroups: comp.std.c Subject: Re: Re: Re: __STDC__ and non-conforming ANSI C compilers Message-ID: <9445@smoke.BRL.MIL> Date: 19 Jan 89 21:31:43 GMT References: <898@ubu.warwick.UUCP> <12570003@hpclsue.HP.COM> Reply-To: gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) Organization: Ballistic Research Lab (BRL), APG, MD. Lines: 118 In article <12570003@hpclsue.HP.COM> sue@hpclsue.HP.COM (Sue Meloy) writes: >But, for syntax extensions and name space pollution, I do feel that it >may be reasonable to define __STDC__. In particular, POSIX requires >additional names that would pollute a strict ANSI name space. Is it >reasonable to say that __STDC__ should not be defined in a POSIX >implementation? Hi, Sue! That's a tough question, because the intention was for an implementation to readily be simultaneously ANSI C conforming and POSIX conforming. Unfortunately, as I discussed here recently, it wasn't specified quite right, so simultaneous conformance, while technically possible, isn't very helpful (since it forces applications to have to do something special to get at some of the POSIX names). Because of this intention, it would be reasonable to have __STDC__ defined as 1 in a POSIX implementation that conformed to ANSI C in every way except for the additional (constrained) names required by POSIX also being visible upon including the standard headers. My current opinion is that in such a case the implementation should probably also predefine _POSIX_SOURCE, but counterarguments can be made to that. (For example, if an application DOES define this symbol itself (as indicated by 1003.1), differently from the implementation, the compiler would squawk.) A very practical question for implementors is whether a C Standard validation test can "gig" them for providing the POSIX extensions in the standard headers. I think the answer to that is very clear: Yes, it can and should. Therefore there needs to be some way to invoke the compiler in both a "pure ANSI (plus allowed extensions)" mode and an "almost ANSI but with POSIX extensions as well" mode. People porting code to such an environment should be advised that the default POSIX mode of invoking the compiler is not ANSI C conformant, but only because of the additional identifiers in the standard headers required by 1003.1, and that if they really need guaranteed C Standard conformance, they need to invoke the other flavor of the compiler. I don't think that defining __STDC__ as 0 is helpful, unless there is some "gentleman's agreement" about what that means (which seems unlikely). >As for syntax extensions (accepted silently), no strictly-conforming >program should be affected. Programs that use the extension would not >receive a diagnostic, rendering the implementation non-standard, so >theoretically __STDC__ should not be defined. Yes, where the C Standard requires a diagnostic, failure to produce one renders the implementation non-conforming. (Section 2.1.1.3.) >Would defining __STDC__ in either of these situations cause problems? To me as an application developer, the important use of __STDC__ is to conditionalize source code so that one branch of the condition has a guaranteed environment available (namely, that specified in the Standard). The other branch is just as bad as it always was. There are extensions which are "transparent", since as you say no strictly-conforming code (which is what one would put into the __STDC__ "true" branch) could be affected by them. For example, adding a __near type qualifier would be such an extension. I see no reason to consider such an implementation as PRACTICALLY non-conforming, so __STDC__ should be 1 if all extensions fall into this category, even though the implementation is not TECHNICALLY a conforming one. So far as any reasonable use of __STDC__ goes, it is IN EFFECT a Standard-conforming implementation, so "lying" about it with __STDC__ in this case can do no practical harm. >If not, is it OK to define it to 1, or should it be 0? __STDC__==0 tells me NOTHING. __STDC__==1 tells me that insofar as strictly-conforming code goes, the implementation will "accept" it (i.e. successfully translate and execute it). That is what I need to know. >Doug, you mentioned that one implementation "guessed wrong" about >your intent for using __STDC__. The assumption was that the __STDC__ tester would care about such things as prototypes and variadic-function support, but not about extra names usurped by the implementation from the application's name space. I actually want to ensure that the name space is not polluted, so I can do things like #include #if __STDC__ /* whatever */ /* "fdopen" is my natural name for the quantity and what I would like to see when I'm debugging */ FONTDESC *fdopen(const char *fontname); /* This function is MINE! I want to call it "fdopen". */ #else /* Just in case we're dealing with UNIX/POSIX etc.: */ #define fdopen my_fdopen /* best of a bad situation */ FONTDESC *fdopen(/*const char *fontname*/); /* But I'll settle for "my_fdopen" if pressed. */ #endif ... { FONTDESC *fd = fdopen("Courier"); ... } Note that if the __STDC__ test results in "true" in a UNIX/POSIX environment, this code will fail to compile. It would have been even worse if it had had conformable type to the function declared in but radically different semantics! If there seems to evolve a general agreement that POSIX implementations are going to define __STDC__ as 1 even though there are a handful of extra names defined in the headers, then I'll simply avoid using those names even though they may be what I wanted to use myself. At least I know what those extra names ARE. I don't think we want to extend that to OTHER such implementation extensions in standard headers, though, because then I would not know what to expect when I include a standard header and would have to give up entirely on the "clean name space" guarantee that I find so valuable. IEEE Std 1003.1 may deserve an exception simply because it had attempted liaison with X3J11 on this (even though it was botched).