TITLE: c++ compiler conformance (Newsgroups: comp.lang.c++.moderated, 2 Feb 2000) WADE: "Bill Wade" > I'd be interested to see resources that document the areas where the C++ > standard says one thing, and mainstream implementations do something else > (often less, sometimes more). > > I'm aware of sites like http://animal.ihug.co.nz/c++/compilers.html that, in > part, tell which parts of the standard are commonly not implemented. I > would like a broader list. > > In practice I find it useful to be able to identify things which > 1) Aren't standard, but work in so many places that they may be profitably > used as long as you test them on each platform. > 2) Are standard, but are commonly not implemented correctly and can > introduce "silent" errors in code that attempts to use them without tests. > [...] AFSHAR: Jamshid Afshar Unfortunately, there are a lot of techniques that are Standard-conforming, but most C++ programmers can't use because so many compiler vendors do a poor job of adhering to the C++ Standard. For example, I'm appending a small program that demonstrates a well-known, standard-conforming technique for ensuring global / singleton objects get constructed and destroyed in the proper order. Too bad Solaris C++ (supposed to be fixed in upcoming 6.0) and g++ (at least 2.7) don't get it right. VC++ 6 gets it right, after changing the code to workaround an access bug in their compiler (argh!). Also annoying and inexcusable is that only one C++ compiler vendors (that I know of -- g++) has taken advantage of the include guard file optimization (see the recent "Redundant include guards" thread). A compiler/preprocessor just has to keep track of which header files had include guards, and then it doesn't have to reopen and scan through the file if it sees it #include'd again. Instead of implementing this simple enhancement, some vendors (eg, VC++) waste their time implementing non-standard, unnecessary extensions like "#pragma once". Oh well, let's see how it goes. Because of lack of competition and, frankly, lack of demand by C++ compiler users (we just take it as a given that we can't portably use many C++ features, so vendors don't devote a lot of resources to it), I'm not sure how much more standard-conforming compilers are going to become. It seems like the last mile to C++ standard-conformance is going to be the slowest. ---------------------------------------------------------------------------- - #include class LogFile { // private ctor&dtor to prevent others from instantiating a LogFile LogFile() { cout << "Constructing LogFile" << endl; } ~LogFile() { cout << "Destroying LogFile" << endl; } public: static LogFile& global(); void output( const char* msg ) { cout << msg << endl; } }; class Foo { Foo() { LogFile::global().output("Constructing Foo"); } ~Foo() { LogFile::global().output("Destroying Foo"); } public: static Foo& global(); }; Foo& Foo::global() { static Foo l; return l; } // Warning: Solaris C++ destroys in the correct order if you happen to // put this definition above Foo::global(). Obviosly, don't rely on this. LogFile& LogFile::global() { static LogFile l; return l; } int main() { // No matter which order the next two statements are in, the LogFile() // is required by the C++ Standard to be destroyed last. // Constructing LogFile // Constructing Foo // Destroying Foo // Destroying LogFile LogFile::global(); Foo::global(); return 0; } (Source: private correspondence, 30 Mar 2000) TRIBBLE: David R Tribble [mailto:david@tribble.com] This isn't entirely fair. It takes a large amount of work to parse include guards (i.e., recognizing them as such) compared to parsing a simple pragma. And by embuing a compiler/preprocessor with the smarts necessary to recognize include guards, you run the risk of getting it wrong in enough cases to annoy the customer even further. Rehash of techniques probably already discussed ahead I take the view that I can do a better job than the compiler in reducing compile time, using common techniques such as: // foo.cpp // System includes #ifndef std_cstdio_h #include #define std_cstdio_h #endif ...etc, for each system header... // Project includes #ifndef my_foo_h #include "foo.h" // #defines my_foo_h #endif ...etc, for each of my local projct headers... ...code goes here... // End foo.cpp On some compilers running on undersized mainframes (where I/O appears to be very expensive), such techniques can reduce compile time from hours to minutes. Yeah, it's a pain, but it's portable and guaranteed effective. TRIBBLE: David R Tribble (david@tribble.com) (Source: private correspondence, 30 Mar 2000) This isn't entirely fair. It takes a large amount of work to parse include guards (i.e., recognizing them as such) compared to parsing a simple pragma. And by embuing a compiler/preprocessor with the smarts necessary to recognize include guards, you run the risk of getting it wrong in enough cases to annoy the customer even further. Rehash of techniques probably already discussed ahead I take the view that I can do a better job than the compiler in reducing compile time, using common techniques such as: // foo.cpp // System includes #ifndef std_cstdio_h #include #define std_cstdio_h #endif ...etc, for each system header... // Project includes #ifndef my_foo_h #include "foo.h" // #defines my_foo_h #endif ...etc, for each of my local projct headers... ...code goes here... // End foo.cpp On some compilers running on undersized mainframes (where I/O appears to be very expensive), such techniques can reduce compile time from hours to minutes. Yeah, it's a pain, but it's portable and guaranteed effective. TRIBBLE: David R Tribble (david@tribble.com) (Source: private correspondence, 30 Mar 2000) Speaking of #pragmas, one thing that annoys me about them is that all vendors choose pragma keywords willy nilly, without considering the consequences of how other vendor's compilers will treat them. In most cases the unrecognized pragmas are simply ignored, it's true, but it seems to me that vendors could reduce the possibilities of collisions by using something akin to namespaces in their pragmas. C99 already does this, by requiring the 'STDC' keyword to appear as the first token in a pragma, and mandating that vendors cannot use this token for their own pragma extensions. Logic dictates that vendors could instead use their own (vendor-specific) token. For example, Microsoft could use '#pragma MSC ...' for its pragmas. This first token would act like a namespace, partitioning the pragmas into vendor-specific spaces. _______________________________________________ cpptips mailing list http://cpptips.hyperformix.com