strings in header files

This is a discussion on strings in header files within the C++ Programming forums, part of the General Programming Boards category; Incidentally... Originally Posted by brewbuck Never, ever, ever, EVER put a using directive in a header file. NEVER. Though never ...

  1. #16
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,636
    Incidentally...
    Quote Originally Posted by brewbuck
    Never, ever, ever, EVER put a using directive in a header file. NEVER.
    Though never is too strong a word here, since a using directive in an inline function in a header file is acceptable since its effects would be restricted to the scope of the function. On a related note, a using declaration in class scope in a header file may be the correct thing to do if one needs to bring in a name from a base class that is otherwise hidden.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  2. #17
    Registered User
    Join Date
    May 2009
    Posts
    242
    Ok, on the main issue, I'm going to conclude that at least until I get sufficiently advanced that I know exactly why I'm doing it (e.g., Laserlight's cases), I just won't use usings in a header.

    To me, anyway, it also seems a little pointless for an inline function declaration, since, at least at my level, those are 1-liners that cost less effort to writing std:: once or twice than to write using, etc. But those exceptions are things I shouldn't need to worry about for a good while.

    I still do have 1 question remaining, emerging mainly from Mario's comment that he likes keeping the #include <iostream>

    At least both the books I've been using have up to now NOT put this in in header files. I'm pretty sure they've avoided #include's altogether in headers. There, I could indeed see an exception if you wanted to declare an inline function using cin, cout, or anything else requiring a header.

    But if you only have prototypes, struct, class declarations, etc. in there, I'm not seeing why to keep it. The reason I started with it in the first place was the hope that it might get the compiler to accept my string, but the #include didn't really have anything to do with that.

  3. #18
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,185
    Quote Originally Posted by Aisthesis View Post
    But if you only have prototypes, struct, class declarations, etc. in there, I'm not seeing why to keep it. The reason I started with it in the first place was the hope that it might get the compiler to accept my string, but the #include didn't really have anything to do with that.
    Well, it sort of does -- if you don't #include <string>, you don't get to have a std::string either. Same for all the containers -- if you even mention that you want to have a std::vector, you have to #include <vector> in that file.

  4. #19
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,438
    Quote Originally Posted by Aisthesis View Post
    I still do have 1 question remaining, emerging mainly from Mario's comment that he likes keeping the #include <iostream>

    At least both the books I've been using have up to now NOT put this in in header files. I'm pretty sure they've avoided #include's altogether in headers. There, I could indeed see an exception if you wanted to declare an inline function using cin, cout, or anything else requiring a header.

    But if you only have prototypes, struct, class declarations, etc. in there, I'm not seeing why to keep it. The reason I started with it in the first place was the hope that it might get the compiler to accept my string, but the #include didn't really have anything to do with that.
    Books usually do that since they assume the reader will include the necessary headers.

    You have to undestand that even during declaration the types you use must be known to the compiler. this is only possible through the #include directive.

    Now you may be mislead into believe it works without the include. I'll give you an example of an apparent lack of #include that compiles just fine:

    Code:
    Header file (test.hpp):
    struct golf
    {
    	std::string fullname; //oops?
    	int handicap;
    };
    
    
    Source File:
    #include <iostream>
    #include "test.hpp"
    
    int main() {
    
     //do nothing
    
    }
    This compiles. Despite the lack of #include <string> in the header file, the compiler has no problems finding the std::string type. Why?

    Because in reality your source file only includes test.hpp after including <iostream>. Since <iostream> itself includes <string> at some point, it works.

    But what happens if you want to use test.hpp somewhere else? You will have to guarantee <string> is included also before "test.hpp". Now, imagine you are grabbing your code in 3 months, or that someone else wants to include "test.hpp". Do you think you will remember then you will need to include <string> on your source file before including "test.hpp"? And what about that other person? Do you think they will even know they need to include <string>?
    Last edited by Mario F.; 08-02-2009 at 03:09 PM.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    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.

  5. #20
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    >> Since <iostream> itself includes <string> at some point, it works.
    I think Mario knows this but I do want to clarify. <iostream> does not officially include <string>, but with some libraries it appears to work because they share common includes.

    The bottom line is to always use a #include when you use something from that header, even if your code is also in a header. In cases where you use the name of something but don't need the full definition, then a forward declaration works, but that is rare with standard library objects. It is not good practice to use something in your header file without #includ'ing the proper header for it.

  6. #21
    Registered User
    Join Date
    May 2009
    Posts
    242
    hey, if you guys wouldn't mind, take a look at the header file I'm getting ready to post from my html translator problem. It compiles and runs without the #include (and using std::string).

    I'm going to leave it the way it is for today anyway. But I'm gathering from the comments here that it's better to throw at least one #include in.

    I'll elaborate on the question in the new thread.

  7. #22
    Registered User
    Join Date
    Jan 2005
    Posts
    7,317
    >> It compiles and runs without the #include (and using std::string).

    That doesn't matter. If you use std::string in that header, you should add the #include <string>.

    Otherwise you'll be wondering why your code mysteriously stops compiling or working later on.

  8. #23
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,438
    Quote Originally Posted by Daved View Post
    I think Mario knows this but I do want to clarify. <iostream> does not officially include <string>, but with some libraries it appears to work because they share common includes.
    Yes, I should have worded it better.

    With MSVC 9.0 this is the include path to the actual declaration of std::string, from the original iostream, to xstring where it is finally declared.

    iostream
    istream
    ostream
    ios
    xlocnum
    streambuf
    xiosbase
    xlocale
    stdexcept
    xstring
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    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.

  9. #24
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,438
    Quote Originally Posted by Aisthesis View Post
    hey, if you guys wouldn't mind, take a look at the header file I'm getting ready to post from my html translator problem. It compiles and runs without the #include (and using std::string).
    I don't think you are listening. It works because of an almost random event. The std::string name is being introduced by some other header. This is pure coincidence. Try to insert your header file somewhere else where std::string is not being declared by some header file and your code will not work.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    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.

  10. #25
    Registered User
    Join Date
    May 2009
    Posts
    242
    "Books usually do that since they assume the reader will include the necessary headers."

    Not in these cases because these are chapters introducing the way to code multi-file programs. It may be coincidence that the examples they used in these chapters didn't NEED the includes, but they're not omitting them here because it's self-evident. They purport to be providing complete code that works.

    "It works because of an almost random event."

    Having the std::string name introduced elsewhere is no coincidence when your header file only includes a prototype that uses it. Thye prototype obviously MUST be elaborated on with a full-scale function definition.

    "The std::string name is being introduced by some other header."

    It can't be. That's the only header file in the program.

  11. #26
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Portugal
    Posts
    7,438
    Quote Originally Posted by Aisthesis View Post
    "Books usually do that since they assume the reader will include the necessary headers."

    Not in these cases because these are chapters introducing the way to code multi-file programs. It may be coincidence that the examples they used in these chapters didn't NEED the includes, but they're not omitting them here because it's self-evident. They purport to be providing complete code that works.
    Please share us the titles, so we start a new sticky thread on books no one should read.

    Quote Originally Posted by Aisthesis View Post
    "It works because of an almost random event."

    Having the std::string name introduced elsewhere is no coincidence when your header file only includes a prototype that uses it. Thye prototype obviously MUST be elaborated on with a full-scale function definition.
    Let's get something straight here. You are NOT declaring a prototype. The only prototypes I know are function prototypes. You are defining a class (or struct, which is a class too). The only thing remotely close to a function prototype that is applied to classes is a class forward declaration. And that is definitely not what you are doing:

    Code:
    class B; // class forward declaration
    
    class A { // class definition
      /* ... */
    };
    So with that off your mind, let's proceed...

    In any case you could be declaring a function and you could be declaring the prototype of a function and you would still be forced to #include the necessary headers for those function arguments or return type:

    Code:
    void myfunc (std::string str); // function declaration, or prototype if you must
    The above function declaration will NOT compile if the std::string identifier is not being declared somewhere in your includes path. Create a new project and try this:

    Code:
    void myfunc (std::string str);
    
    int main() {
        // do nothing
    }
    
    void myfunc (std::string str) {
        // do nothing
    }
    It will fail to compile.

    Quote Originally Posted by Aisthesis View Post
    "The std::string name is being introduced by some other header."

    It can't be. That's the only header file in the program.
    Please show us your code. Mention also which compiler you are using.
    Last edited by Mario F.; 08-02-2009 at 08:44 PM.
    The programmer’s wife tells him: “Run to the store and pick up a loaf of bread. If they have eggs, get a dozen.”
    The programmer comes home with 12 loaves of bread.


    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.

  12. #27
    and the hat of sweating
    Join Date
    Aug 2007
    Location
    Toronto, ON
    Posts
    3,545
    Try this... In your .cpp file, you must be doing something like this:
    Code:
    #include <string>
    #include "Your_Header.h"
    ...
    So try switching the #include statements around so that you include your header file before any of the standard header files. Compile it and watch the errors you get.
    Now add #include <string> back into your header file and see if those errors disappear.
    "I am probably the laziest programmer on the planet, a fact with which anyone who has ever seen my code will agree." - esbo, 11/15/2008

    "the internet is a scary place to be thats why i dont use it much." - billet, 03/17/2010

  13. #28
    Registered User
    Join Date
    May 2009
    Posts
    242
    cpjust's restatement is the way I understood it.

    Books: Prata, C++ Primer Plus; Gaddis, Starting out with C++

    I've been showing the code since the beginning.

    And, sorry, I did mistakenly say that it was only prototypes when a huge feature of the header file was a struct declaration. Other than those points, I really feel like this thread has run its course and the issue is about as clear as its going to get.

  14. #29
    Registered User
    Join Date
    May 2009
    Posts
    242
    sorry, one omission still: compiler is MS Visual C++ 2008 Express

Page 2 of 2 FirstFirst 12
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Header files and multiple definitions
    By sjweinberg in forum C++ Programming
    Replies: 16
    Last Post: 07-17-2009, 05:59 PM
  2. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 09:33 AM
  3. Using c++ standards
    By subdene in forum C++ Programming
    Replies: 4
    Last Post: 06-06-2002, 09:15 AM
  4. more header files
    By Unregistered in forum C++ Programming
    Replies: 2
    Last Post: 10-28-2001, 12:56 PM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21