Thread: compiler isn't enforcing standards strictly enough

  1. #1
    Registered User
    Join Date
    Sep 2006
    Posts
    835

    compiler isn't enforcing standards strictly enough

    I wrote a little test program using numeric_limits, but forgot to include <limits>. It compiles anyway without complaints using GCC 4.1.1. I tried using the -ansi and -pedantic options with no effect. Why is the compiler allowing this, and are there tools available in Linux for testing the code more strictly?

  2. #2
    Registered User
    Join Date
    Dec 2006
    Posts
    30
    some of your other headers included it

  3. #3
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Hmm.

    Could you post the little test program?

    You aren't doing something silly like using namespace std;?
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  4. #4
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    The following should have
    Code:
    #include <limits>
    but compiles without it.

    Code:
    #include <iostream>
    
    int main() {
      std::cout << "Maximum value of float is " << std::numeric_limits<float>::max() << "\n";
      std::cout << "Maximum value of double is " << std::numeric_limits<double>::max() << "\n";
    }

  5. #5
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    Hm.

    My gcc seems to have <iostream> #including <istream> which happens to #include <limits>.

    An artifact of that, no doubt. But I don't know whether or not the standard guarantees such behavior. A number of things are left to the programmer.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  6. #6
    Registered User
    Join Date
    Dec 2006
    Posts
    30
    if you don't include anything, it will give an error; to show that it indeed does complain
    Code:
    int main() {
      return INT_MAX;
    }

  7. #7
    Just Lurking Dave_Sinkula's Avatar
    Join Date
    Oct 2002
    Posts
    5,005
    If the standard requires that...
    basic_istream<charT,traits>& getline(char_type* s, streamsize n);
    23 Returns: getline(s,n,widen(’\n’))
    basic_istream<charT,traits>&
    ignore(int n = 1, int_type delim = traits::eof());
    24 Effects: Extracts characters and discards them. Characters are extracted until any of the following occurs:
    — if n != numeric_limits<int>::max() (18.2.1), n characters are extracted
    — endoffile
    occurs on the input sequence (in which case the function calls setstate(eofbit),
    which may throw ios_base::failure (27.4.4.3));
    It seems somewhat implicit that <limits> is #included.

    But I don't' know C++ that well.
    7. It is easier to write an incorrect program than understand a correct one.
    40. There are two ways to write error-free programs; only the third one works.*

  8. #8
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    I guess the more general question is, is the exact way that standard headers are #include'd in each other guaranteed by the standard? If not, then there needs to be a lint-like tool to check the headers.

  9. #9
    Its hard... But im here swgh's Avatar
    Join Date
    Apr 2005
    Location
    England
    Posts
    1,688
    I think you should bring this up with Bjarne Stroustup (*check spelling)
    Double Helix STL

  10. #10
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    AFAIK, there is no specific requirement in the standard that standard headers either #include each other, or that they avoid #include'ing each other.

    However standard headers specify relationships between types or objects in header files (eg <iostream> includes a declaration of cin, which is an object of type istream, which is a type declared in <istream>). One way of ensuring that the standard headers don't break "one definition rule" would be for them to #include each other. This is probably what has been done with gcc, and explains what is happening. Another way would be for the headers to employ "compiler magic" to ensure things work as intended; with such a compiler, the original code would probably break unless all the required headers were explicitly #include'd.

    Which comes back to a basic guideline: if you are using the standard library, #include all the headers that correspond to the features you are using. The standard does specify that all standard headers can be safely #include'd more than once, so if there are interdependencies, you won't be hurt by following such a guideline.

  11. #11
    MFC killed my cat! manutd's Avatar
    Join Date
    Sep 2006
    Location
    Boston, Massachusetts
    Posts
    870
    It's Bjarne Stroustrup.
    Silence is better than unmeaning words.
    - Pythagoras
    My blog

  12. #12
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    Quote Originally Posted by grumpy
    AFAIK, there is no specific requirement in the standard that standard headers either #include each other, or that they avoid #include'ing each other.

    However standard headers specify relationships between types or objects in header files (eg <iostream> includes a declaration of cin, which is an object of type istream, which is a type declared in <istream>). One way of ensuring that the standard headers don't break "one definition rule" would be for them to #include each other. This is probably what has been done with gcc, and explains what is happening. Another way would be for the headers to employ "compiler magic" to ensure things work as intended; with such a compiler, the original code would probably break unless all the required headers were explicitly #include'd.

    Which comes back to a basic guideline: if you are using the standard library, #include all the headers that correspond to the features you are using. The standard does specify that all standard headers can be safely #include'd more than once, so if there are interdependencies, you won't be hurt by following such a guideline.
    That's my intent, but it's just too easy to forget to #include some of them, and then, when the compiler doesn't complain due to indirect #include's, to think that I've written standards-compliant code, give it to someone else, and be embarrassed when they can't compile it. Anyone know if there is something lint-like for checking this?

  13. #13
    Registered User
    Join Date
    Sep 2006
    Posts
    835
    I suppose one way of doing it is to deliberately write headers that don't use any internal #include's not required by the standard. If the code compiles using those, then it's okay.

  14. #14
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    PC-Lint detects missing headers even taking into consideration dependencies. That's the only lint I use though... so I dunno about others. You can also gain some quick insight into GCC standard header dependencies implementation by compiling with the -H switch which will list all headers used.

    Regardless, the number of headers that should be included is not that big.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  15. #15
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    > I suppose one way of doing it is to deliberately write headers that don't use any internal #include's not required by the standard. If the code compiles using those, then it's okay.

    I think you are taking this header thing a little too far. Header dependencies are not something that works against you. Missing a <string> is certainly not nice to see, but that's your responsibility. Not something that you can blame on how the compiler implements header dependencies. It does so because it needs those dependencies. Much the same way you implement your own header dependencies in your code and can't expect to be blamed if someone else doesn't include the correct headers.

    The problem here is solved not by knowing how your compiler implements the standard library. It is solved by you studying the standard library and knowing which headers it uses and where its objects and functions are located.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. strictly speaking standards, do classes get capitalized
    By *DEAD* in forum C++ Programming
    Replies: 4
    Last Post: 08-11-2007, 11:26 PM
  2. C Compiler and stuff
    By pal1ndr0me in forum C Programming
    Replies: 10
    Last Post: 07-21-2006, 11:07 AM
  3. I can't get this new compiler to work.
    By Loduwijk in forum C++ Programming
    Replies: 7
    Last Post: 03-29-2006, 06:42 AM
  4. how to call a compiler?
    By castlelight in forum C Programming
    Replies: 3
    Last Post: 11-22-2005, 11:28 AM
  5. Help With finding a compiler
    By macman in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 04-15-2005, 08:15 AM