dfenyes@thesis1.hsch.utexas.edu (David Fenyes) (02/20/91)
Hello, Here's the question: Everybody knows that ANSI C compilers with ANSI preprocessors should have __STDC__ #defined to 1, and K&R compilers with K&R cpp don't have __STDC__ #defined at all. The question is: Does an ANSI cpp ALWAYS #define __STDC__, even if it is used intentionally with a K&R compiler (#defined to 0)? Mark Williams uses an ANSI cpp with their non-ANSI compiler, and #defines __STDC__ to 0, which causes all sorts of problems when code tests #ifdef __STDC__ . . . (rather than #if __STDC__). Who is the offender? MWC, or those #ifdef'ers out there? It makes sense to #define __STDC__ so the code can take advantage of the ANSI cpp features, while still not using ANSI prototypes, etc. If anyone knows the answer from the ANSI documents, please let me know, or post to the net. I'd be glad to summarize any info mailed to me for the net. Thanks, David. -- David Fenyes dfenyes@thesis1.hsch.utexas.edu University of Texas Medical School Houston, Texas
gwyn@smoke.brl.mil (Doug Gwyn) (02/20/91)
In article <4755@lib.tmc.edu> dfenyes@thesis1.hsch.utexas.edu (David Fenyes) writes: >The question is: Does an ANSI cpp ALWAYS #define __STDC__, even if it >is used intentionally with a K&R compiler (#defined to 0)? It does whatever it does. The C standard constrains only conforming implementations, which must in effect predefine __STDC__ to 1. Non-conforming implementations are outside the scope of the standard. Having said that, I would add that implementors who #define __STDC__ to anything at all in non-conforming variants of their compilers are not doing anyone a favor, and I wish they would desist from that practice.
henry@zoo.toronto.edu (Henry Spencer) (02/21/91)
In article <4755@lib.tmc.edu> dfenyes@thesis1.hsch.utexas.edu (David Fenyes) writes: >The question is: Does an ANSI cpp ALWAYS #define __STDC__, even if it >is used intentionally with a K&R compiler (#defined to 0)? An "ANSI cpp"? There is no such thing; there are only ANSI C implementations. ANSI C does not specify any aspect of the behavior that results if you use part of an ANSI C implementation in conjunction with something else. It does not even promise that this is possible at all, since many C compilers do not *have* a separate preprocessor. >Mark Williams uses an ANSI cpp with their non-ANSI compiler, and >#defines __STDC__ to 0, which causes all sorts of problems when code >tests #ifdef __STDC__ . . . (rather than #if __STDC__). > >Who is the offender? MWC, or those #ifdef'ers out there? MWC. Defining __STDC__ to be anything in a non-ANSI environment is a dumb thing to do. There is no portable meaning for a __STDC__ value of 0. -- "Read the OSI protocol specifications? | Henry Spencer @ U of Toronto Zoology I can't even *lift* them!" | henry@zoo.toronto.edu utzoo!henry
dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (02/22/91)
In <1991Feb20.175702.28682@zoo.toronto.edu> henry@zoo.toronto.edu
(Henry Spencer) writes:
...since many C compilers do not *have* a separate preprocessor.
I may have to eat my words, but after extensive searching, I haven't
yet found any commercially available C compiler that wasn't accompanied
by a separately invokable preprocessor.
--
Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com>
UUCP: oliveb!cirrusl!dhesi
henry@zoo.toronto.edu (Henry Spencer) (02/22/91)
In article <2961@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes: > ...since many C compilers do not *have* a separate preprocessor. > >I may have to eat my words, but after extensive searching, I haven't >yet found any commercially available C compiler that wasn't accompanied >by a separately invokable preprocessor. Note that the two statements are not entirely inconsistent: it is quite possible to invoke only the preprocessor functionality of a compiler that does not break it out as a separate program. I assure you that there are quite a few compilers that integrate the preprocessor into the scanner; the Whitesmiths compiler was the first. In fact, when implementing from scratch, it makes little sense to separate preprocessor and scanner, since it means tokenizing the source twice. I suspect that most any sensible implementor would provide a way to invoke the preprocessor functionality only. However, there is no requirement to do so, and no guarantee that an ANSI implementation will do so... which was the point of my original posting. -- "Read the OSI protocol specifications? | Henry Spencer @ U of Toronto Zoology I can't even *lift* them!" | henry@zoo.toronto.edu utzoo!henry
steve@taumet.com (Stephen Clamage) (02/23/91)
dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes: >In <1991Feb20.175702.28682@zoo.toronto.edu> henry@zoo.toronto.edu >(Henry Spencer) writes: > ...since many C compilers do not *have* a separate preprocessor. >I may have to eat my words, but after extensive searching, I haven't >yet found any commercially available C compiler that wasn't accompanied >by a separately invokable preprocessor. Oregon C/C++ (from Oregon Software) is a single program which includes integral preprocessing. That is, input is preprocessed on the fly, and there is no separate preprocessor output required. There is no separate preprocessor program. However, you may ask for preprocessor output as an option, so this may qualify as a "separately invokable preprocessor". -- Steve Clamage, TauMetric Corp, steve@taumet.com
meissner@osf.org (Michael Meissner) (02/23/91)
In article <2961@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes: | In <1991Feb20.175702.28682@zoo.toronto.edu> henry@zoo.toronto.edu | (Henry Spencer) writes: | | ...since many C compilers do not *have* a separate preprocessor. | | I may have to eat my words, but after extensive searching, I haven't | yet found any commercially available C compiler that wasn't accompanied | by a separately invokable preprocessor. The Data General AOS/VS C compiler (and the DG/UX MV/Eclipse C compiler which was the same beast repackaged for unix) had the preprocessor as part of the tokenizer. This is from the horse's mouth, since I wrote the compiler front end, and the preprocessor never was a separate program. It started shipping in the 1982 time frame. -- Michael Meissner email: meissner@osf.org phone: 617-621-8861 Open Software Foundation, 11 Cambridge Center, Cambridge, MA, 02142 Considering the flames and intolerance, shouldn't USENET be spelled ABUSENET?
barmar@think.com (Barry Margolin) (02/23/91)
In article <2961@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes: >I may have to eat my words, but after extensive searching, I haven't >yet found any commercially available C compiler that wasn't accompanied >by a separately invokable preprocessor. As usual, the best place to look for an unusual C compiler is Symbolics. Their preprocessor may be invokable separately, but it isn't documented and I think it outputs tokens, not text. -- Barry Margolin, Thinking Machines Corp. barmar@think.com {uunet,harvard}!think!barmar
blarson@blars (02/23/91)
In article <2961@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes: >I may have to eat my words, but after extensive searching, I haven't >yet found any commercially available C compiler that wasn't accompanied >by a separately invokable preprocessor. Prime C for their 50 series. The output of Microware's os9/68k C compiler cpp is not legal C, and cannot be used with other C compilers. -- blarson@usc.edu C news and rn for os9/68k! -- Bob Larson (blars) blarson@usc.edu usc!blarson Hiding differences does not make them go away. Accepting differences makes them unimportant.
peter@ficc.ferranti.com (Peter da Silva) (02/26/91)
I first ran into a C compiler with no separate preprocessor and no way of running just the preprocessor in 1981. The compiler was the BDS compiler for CP/M. -- Peter da Silva. `-_-' peter@ferranti.com +1 713 274 5180. 'U` "Have you hugged your wolf today?"
rfg@NCD.COM (Ron Guilmette) (03/03/91)
In article <15260@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: > >Having said that, I would add that implementors who #define __STDC__ >to anything at all in non-conforming variants of their compilers are >not doing anyone a favor, and I wish they would desist from that >practice. I assume that you also get irrate about implementors who define __STDC__ to something other than 1. AT&T's CI5 C compiler (for SVR4) can do any one of the following three possible things (depending upon the options used): leave __STDC__ undefined predefine __STDC__ to 0 predefine __STDC__ to 1 The corresponding three "compilation modes" are (respectively): compile using both K&R and ANSI rules but use K&R rules in cases where there are conflicts compile using both K&R and ANSI rules but use ANSI rules in cases where there are conflicts compile using only ANSI rules (but with some standard comforming extensions) -- // Ron Guilmette - C++ Entomologist // Internet: rfg@ncd.com uucp: ...uunet!lupine!rfg // New motto: If it ain't broke, try using a bigger hammer.
gwyn@smoke.brl.mil (Doug Gwyn) (03/05/91)
In article <4203@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes: >I assume that you also get irrate about implementors who define __STDC__ >to something other than 1. I have no problem with an otherwise CONFORMING implementation defining __STDC__ to something other than 1, although why would it? At least that does not cause problems for strictly conforming applications. >The corresponding three "compilation modes" are (respectively): But that is NOT what __STDC__ means according to the C standard, which is why there is a problem with people trying to use it for other purposes.
fred@mindcraft.com (Fred Zlotnick) (03/07/91)
In article <15381@smoke.brl.mil> gwyn@smoke.brl.mil (Doug Gwyn) writes: >In article <4203@lupine.NCD.COM> rfg@NCD.COM (Ron Guilmette) writes: >>I assume that you also get irrate about implementors who define __STDC__ >>to something other than 1. > >I have no problem with an otherwise CONFORMING implementation defining >__STDC__ to something other than 1, although why would it? At least >that does not cause problems for strictly conforming applications. But it CAN cause problems (in addition to which, such an implementation is no longer conforming according to section 3.8.8): since we know that nonconforming implementations do in fact sometimes define __STDC__ to something other than 1, it would be useful to protect your code by using the test #if __STDC__ == 1 rather than #ifdef __STDC__ This works if __STDC__ is not defined, since (according to 3.8.1) it is "replaced with the pp-number 0". But it won't give the desired result if an "otherwise CONFORMING implementation" has __STDC__ defined to a value not 1. You could argue that nonconforming implementations are free to do whatever they like, including defining __STDC__ to be 1. But this would be nasty, and in practice no intentionally nonconforming implementation is likely to do it. Fred Zlotnick | #include <std.disclaimer> fred@mindcraft.com | #include <brilliant.quote> ...!{decwrl,ames,hpda}!mindcrf!fred |
dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) (03/07/91)
In <668288453.3046@mindcraft.com> fred@mindcraft.com (Fred Zlotnick)
recommends the test
> #if __STDC__ == 1
to detect nonconforming implementations. Unfortunately there are
two problems with this.
First, it is quite possible that a future ANSI C standard will bump up
the value of __STDC__ to 2, thus breaking code that assumes that
(__STDC__ != 1) implies (not standard C).
Second, some existing nonconforming implementations of C will
fail to compile expressions like
#if something == something.
Now you may say these implementations aren't C, and you might be right,
but they are *called* C by many users, and they will be upset that
ostensibly portable C code won't compile. Truly defensive programmers
assume that the preprocessor does not understand C expressions. Such
flaky implementations are fortunately dying out, but I could easily
ruffle through my old disks and find a few that aren't quite dead yet.
--
Rahul Dhesi <dhesi%cirrusl@oliveb.ATC.olivetti.com>
UUCP: oliveb!cirrusl!dhesi
em@dce.ie (Eamonn McManus) (03/08/91)
fred@mindcraft.com (Fred Zlotnick) writes: >... since we know that >nonconforming implementations do in fact sometimes define __STDC__ to >something other than 1, it would be useful to protect your code by using >the test > #if __STDC__ == 1 >rather than > #ifdef __STDC__ There are problems with that, though, quite apart from otherwise conforming hypothetical implementations that define __STDC__ to be other than 1. The replacement of undefined identifiers by 0 may have been a de facto Unix standard but it was nowhere mentioned in K&R1 so it would have been reasonable for a pre-standard implementation to make it an error for a #if to contain an undefined identifier. If I want my code to run on pre-standard implementations (which presumably I do if I care about __STDC__) then I am reluctant to depend on #if __STDC__ or #if __STDC__ == 1 rather than #ifdef __STDC__ which would have been safe had it not been for cretinous implementors who made half-standard implementations with __STDC__ defined but 0. , Eamonn
rbutterw@watmath.waterloo.edu (Ray Butterworth) (03/08/91)
In article <2986@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes: >First, it is quite possible that a future ANSI C standard will bump up >the value of __STDC__ to 2, thus breaking code that assumes that >(__STDC__ != 1) implies (not standard C). The failure to fully define __STDC__ was obviously a mistake, and some vendors have thoroughly abused it. Perhaps the next version of the standard could denegrate __STDC__ and introduce a new definition, say something like #define __ANSI_X3_159__ 1989 and explicitly say that #if defined(__ANSI_X3_159__) is the recommended test for an ANSI Standard compiler. One could also use tests such as #if __ANSI_X3_159__ < 2001 #if __ANSI_X3_159__ == 1989 to check for the version of the Standard. They should also state that if the symbol is defined with any value other than those explicitly listed in the standard, the compiler must generate a fatal error, rather than leaving the behaviour as undefined as it is now with __STDC__. If they really like the __STDC__ name though, they could always say the same as above, but with (__STDC__ == 1) having the same meaning as (__STDC__ = 1989), but using a new symbol would probably avoid confusion.
steve@taumet.com (Stephen Clamage) (03/09/91)
rbutterw@watmath.waterloo.edu (Ray Butterworth) writes: >In article <2986@cirrusl.UUCP> dhesi%cirrusl@oliveb.ATC.olivetti.com (Rahul Dhesi) writes: >>First, it is quite possible that a future ANSI C standard will bump up >>the value of __STDC__ to 2, thus breaking code that assumes that >>(__STDC__ != 1) implies (not standard C). >The failure to fully define __STDC__ was obviously a mistake, >and some vendors have thoroughly abused it. Wait a minute! My copy of X3.159-1989 says __STDC__ is defined as "the decimal constant 1". That seems about as clear and fully-defined as it could be. A processor which defines it to be some other value is not in compliance with the Standard. The purpose of a standard is act as a contract between the compiler writer and the compiler user; if the user writes a conforming program, the compiler will behave in a predictable way. A processor might intend not to be in compliance with the standard, in which case all bets are off. -- Steve Clamage, TauMetric Corp, steve@taumet.com
gwyn@smoke.brl.mil (Doug Gwyn) (03/11/91)
In article <668288453.3046@mindcraft.com> fred@mindcraft.com (Fred Zlotnick) writes: >>I have no problem with an otherwise CONFORMING implementation defining >>__STDC__ to something other than 1, although why would it? At least >>that does not cause problems for strictly conforming applications. >But it CAN cause problems (in addition to which, such an implementation >is no longer conforming according to section 3.8.8): since we know that >nonconforming implementations do in fact sometimes define __STDC__ to >something other than 1, it would be useful to protect your code by using >the test > #if __STDC__ == 1 >rather than > #ifdef __STDC__ The problem is that __STDC__ is likely to be set to 2 for an implementation that conforms to an upward-compatible future revision of the C standard, so #ifdef __STDC__ is the nicest way for current strictly-conforming programs to accommodate both X3.159-1989 conforming implementations and our best estimate of X3.159-199x conforming implementations. Unfortunately, use of #if some_func(__STDC__) implies that the program is trying to determine whether or not to use some system-specific substitute code for features that may not exist in non-conforming implementations. I believe the intention of X3J11 was that __STDC__ would be useful for this purpose, but some C vendors have spoiled that by "helpfully" defining __STDC__ in their non-conforming implementations. In fact I have seen __STDC__ defined as 1 in some non-conforming implementations. The practical effect is that you have the non-conforming vendors to thank for making __STDC__ useless in portable code. Instead, you must somehow devise your own solution to this environment testability issue. What we have done locally is for our universal configuration header <std.h> to define a macro STD_C as either 0 or 1, 0 meaning not a conforming implementation and 1 meaning conforming to X3.159-1989. (Other values reserved for possible future revisions of the standard.) One of the first steps in porting software is to edit <std.h> to correctly set STD_C as well as some other system-dependent standard macros etc.
gwyn@smoke.brl.mil (Doug Gwyn) (03/11/91)
In article <1991Mar7.194733.18150@watmath.waterloo.edu> rbutterw@watmath.waterloo.edu (Ray Butterworth) writes: >The failure to fully define __STDC__ was obviously a mistake, >and some vendors have thoroughly abused it. >Perhaps the next version of the standard could denegrate __STDC__ >and introduce a new definition, say something like > #define __ANSI_X3_159__ 1989 The real problem is that the standard can constrain only the behavior of CONFORMING implementations; nonconforming implementations can do whatever they please, including pretending to be standard conformant. Your suggestions did not address this fundamental problem any better than the existing specification for __STDC__ did. I am of the opinion that there is no method by which any standard could solve the problem.
wirzenius@cc.helsinki.fi (Lars Wirzenius) (03/12/91)
In article <lampblack@dce.ie>, em@dce.ie (Eamonn McManus) writes: > If I want my code to run on pre-standard implementations (which presumably > I do if I care about __STDC__) then I am reluctant to depend on > #if __STDC__ > or > #if __STDC__ == 1 > rather than > #ifdef __STDC__ > which would have been safe had it not been for cretinous implementors who > made half-standard implementations with __STDC__ defined but 0. How about: #ifndef STD_C # ifdef __STDC__ # if __STDC__ == 1 # define STD_C # endif # endif #endif and then code the rest of the program depending on STD_C instead of __STDC__? Incidentally, I would think that it would be better (or at least more useful) to use constants that describe characteristics of the system, rather than conformance to the standard. For example, I think prototypes are available in several non-standard (or almost standard) implementations, which don't do the Right Thing for __STDC__. Another example is header files. The standard introduces <limits.h> (doesn't it?), which may or may not be available in non-standard implementations. It might be a local enchancement to make standard conforming programs to compile a teeny bit easier, but might not be available on other sites with the same C implementation. -- Lars Wirzenius wirzenius@cc.helsinki.fi
rbutterw@watmath.waterloo.edu (Ray Butterworth) (03/12/91)
In article <622@taumet.com> steve@taumet.com (Stephen Clamage) writes: >rbutterw@watmath.waterloo.edu (Ray Butterworth) writes: >>The failure to fully define __STDC__ was obviously a mistake, >>and some vendors have thoroughly abused it. >Wait a minute! My copy of X3.159-1989 says __STDC__ is defined as >"the decimal constant 1". That seems about as clear and fully-defined >as it could be. By "fully define" I meant that it should mention its intended use and explicitly forbid other uses. >From: gwyn@smoke.brl.mil (Doug Gwyn) >In article <1991Mar7.194733.18150@watmath.waterloo.edu> rbutterw@watmath.waterloo.edu (Ray Butterworth) writes: >>Perhaps the next version of the standard could denegrate __STDC__ >>and introduce a new definition, say something like >> #define __ANSI_X3_159__ 1989 >The real problem is that the standard can constrain only the behavior >of CONFORMING implementations; nonconforming implementations can do >whatever they please, including pretending to be standard conformant. If instead of simply saying that __STDC__ will be 1, the Standard had explicitly said something like __STDC__ will be 1 for X3.159-1989, will have other values for later versions of the standard, and all values of this macro are reserved by the Standard, things would have been better. Sure, it could still be abused, but there would be less justification for the abuse. Simply saying that it is 1 made it very easy for some people to interpret this as meaning that one should define it as something else to indicate non conformance. >Your suggestions did not address this fundamental problem any better >than the existing specification for __STDC__ did. I am of the opinion >that there is no method by which any standard could solve the problem. Certainly there is no guaranteed solution, but one can make things more difficult to abuse. The name ANSI_X3_159 sort of indicates that the name belongs to ANSI Standard C. The current (presumptuous) name could (and is) easily claimed by anyone else that wants to declare their version as "standard" (and not necessarily your standard).