Path: utzoo!utgpu!attcan!uunet!auspex!guy From: guy@auspex.UUCP (Guy Harris) Newsgroups: comp.std.c Subject: Re: __STDC__ and non-conforming ANSI C compilers Message-ID: <860@auspex.UUCP> Date: 18 Jan 89 07:03:54 GMT References: <9391@smoke.BRL.MIL> <8731@megaron.arizona.edu> <9405@smoke.BRL.MIL> Reply-To: guy@auspex.UUCP (Guy Harris) Organization: Auspex Systems, Santa Clara Lines: 79 >The Standard is obviously unable to specify anything about __STDC__ >for a non-conforming implementation, because by definition such >implementations do not obey the Standard! Would putting a recommendation in the Rationale that non-conforming implementations not define __STDC__ at all help? >I've explained that above. "Rough ANSI compliance" is meaningless >and useless to the portable application programmer. "Strict ANSI >compliance", on the other hand, is a meaningful notion of considerable >utility to the programmer. In order for it to HAVE this utility, >though, we need the symbol __STDC__ reserved for making the >distinction. How meaningful is its antithesis? "Strict ANSI non-compliance" could mean anything from "they define 'ferror' as a macro in " to "this is really a Pascal compiler, and we played a cruel joke on the customer by selling it as a non-compliant C compiler." In other words, I can sort of see what goes in between "#if __STDC__" and "#endif", as long as there's no "#else", say, at that level between them; if you stick a "#else" in there at that level, what goes between it and "#endif"? If the the question really can't be answered meaningfully, I don't see that "#if __STDC__" is a useful test; the only useful tests I could see would be something such as #if __STDC__ == 2 #define NOALIAS noalias #elif __STDC__ == 1 #define NOALIAS #endif once the second ANSI C standard comes out after all the problems noted with "noalias" have been solved :-). Now one form of "strict ANSI non-compliance" (i.e., the negation of "strict ANSI compliance") that could be useful would be that exhibited by an implementation that conforms to ANSI C except for POSIX items that might get in the way. This would include declarations of functions, and definition of macros, that POSIX mentions in connection with some include file also mentioned in ANSI C. For instance, would probably define "ferror" as a macro. Doing so breaks ANSI compliance, as I understand it; however, doing so is also quite useful to writers of portable applications, with "portable" meaning "portable to POSIX-conformant systems" rather than "portable to ANSI C-conformant systems. POSIX does not, as I remember, require ANSI C conformance; thus, you might want to write applications that are portable to POSIX-conformant systems that can be built and run both on ANSI C-conformant and "many" ANSI C-non-conformant systems. Yes, I know that in some deep sense they can't rely on any particular part of the ANSI C-non-conformant systems' C implementations; however, this nonwithstanding, such applications will be written *anyway*, since the writers may not be able to postpone paying their mortgage bills until such time as major vendors come out with their ANSI C compilers. By and large, they will probably assume "recent PCC" C, and hope for the best. Given that, for example, I could see portable code being written ("portable" meaning "portable to ANSI-conformant POSIX-conformant systems, and most POSIX-conformant systems that implement 'recent PCC' C"), with some #ifdef controlling the use of function prototypes or any of a number of other things. One possibility for these #ifdef might be specific names for particular functions; unfortunately, there's no standard for those names, so the writer can't assume something and hope for the best. Unfortunately, alternatives involving __STDC__ have the problems you list. I don't think there's anything that POSIX defines that says "this implementation is ANSI C, with the exception of this specified list of extra goobers in the namespace"; if there isn't, it's too late to fix it in POSIX. The best I see that could be done here is to make a strong recommendation that POSIX vendors define __ANSI_C_EXCEPT_FOR_POSIX_STUFF__ (or some other specified name) to match what __STDC__ would have been defined as had the "allow POSIX stuff" flag not been given to the compiler.