Thread: Setting up headers, functions etc.

  1. #16
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Well no, not really...
    If A includes B, then B includes A, then A will again include B, thus creating a circular reference. The compiler will complain. With header guards, I believe that Header B will see an empty A, thus the compiler complains that all the declarations in A are undefined (because your headerguards removes the file contents).
    That's the scenario I was refering to

  2. #17
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    It means that if A is included first, it includes B, which tries to include A, but since A has already defined its header guards, its contents aren't parsed again. Thus, B complains about missing definitions.
    If B is included first, it's A which complains.

    In such cases, you just have to keep track of your dependencies. You have to do that anyway. But recursive header includes are evil.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  3. #18
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by CornedBee View Post
    In such cases, you just have to keep track of your dependencies. You have to do that anyway. But recursive header includes are evil.
    Yes, they are, and that's why I take care to include other headers within headers.
    If a header does not use a specific type (only declarations of it), and no declarations inside that type (like a class or enum in a class), then usually telling the compiler that the class exists is usually enough. You can later include the real header inside the .cpp file.

  4. #19
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Yes, they are, and that's why I take care to include other headers within headers.
    If a header does not use a specific type (only declarations of it), and no declarations inside that type (like a class or enum in a class), then usually telling the compiler that the class exists is usually enough. You can later include the real header inside the .cpp file.
    And then you need TWO header files with partially the same content (or some other duplication of declarations). This is a recipe for making subtle problems due to differing definitions - less of a problem in C++ than C, but still.

    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  5. #20
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    So create a _fwd header. xyz.hpp contains the full class definitions, xyz_fwd.hpp only the forward declarations.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #21
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by matsp View Post
    And then you need TWO header files with partially the same content (or some other duplication of declarations). This is a recipe for making subtle problems due to differing definitions - less of a problem in C++ than C, but still.

    --
    Mats
    Then you have to change both files if some declaration chages.
    I find it best to try to avoid code and such that would require headers to require a full declaration, so you can get away with just declaring a enum or class exists. This way you're fool-proof if that condition occours.

  7. #22
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by Elysia View Post
    Then you have to change both files if some declaration chages.
    I find it best to try to avoid code and such that would require headers to require a full declaration, so you can get away with just declaring a enum or class exists. This way you're fool-proof if that condition occours.
    Well, you can of course isolate some parts of your code, but if you create a class that is supposed to be used elsewhere [and not just held as a pointer to the class], then you do need to declare what the class looks like, or your code will not be able to use the class.

    Under some circumstances, you find yourself with mutual dependancy - and of course, you can USUALLY solve that with one bigger header-file that contains two classes that relate to each other. But if both classes are rather large, that becomes a bit unwieldy - so you need to put some of it in one header, and the rest in another header. In this case, CornedBee's solution is the right one: Split one of the header files into a forward declaring part, e.g. A_fwd.h, and include that in both A.h and B.h.

    Avoiding this is probably a generally good principle, but some things can only be avoided so far without jumping through hoops and making the code more obscure [e.g. using void pointers that are cast into class pointers in the implementation - makes for higher risk of bugs and more potential problems, and not worth it.]


    --
    Mats
    Compilers can produce warnings - make the compiler programmers happy: Use them!
    Please don't PM me for help - and no, I don't do help over instant messengers.

  8. #23
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by matsp View Post
    Well, you can of course isolate some parts of your code, but if you create a class that is supposed to be used elsewhere [and not just held as a pointer to the class], then you do need to declare what the class looks like, or your code will not be able to use the class.
    And that's why you usually put code in .cpp files and avoid them in header files. Although usually templates are troublesome on this. But agreed.

    Under some circumstances, you find yourself with mutual dependancy - and of course, you can USUALLY solve that with one bigger header-file that contains two classes that relate to each other. But if both classes are rather large, that becomes a bit unwieldy - so you need to put some of it in one header, and the rest in another header. In this case, CornedBee's solution is the right one: Split one of the header files into a forward declaring part, e.g. A_fwd.h, and include that in both A.h and B.h.
    Agreed

    Avoiding this is probably a generally good principle, but some things can only be avoided so far without jumping through hoops and making the code more obscure [e.g. using void pointers that are cast into class pointers in the implementation - makes for higher risk of bugs and more potential problems, and not worth it.]


    --
    Mats
    Absolutely agree. Under no circuimstance should you change type because you can't include the header for the declaration of the type in question.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Is it legal to have functions within functions?
    By Programmer_P in forum C++ Programming
    Replies: 13
    Last Post: 05-25-2009, 11:21 PM
  2. An array of macro functions?
    By someprogr in forum C Programming
    Replies: 6
    Last Post: 01-28-2009, 07:05 PM
  3. Replies: 7
    Last Post: 11-17-2008, 01:00 PM
  4. API "Clean Up" Functions & delete Pointers :: Winsock
    By kuphryn in forum Windows Programming
    Replies: 2
    Last Post: 05-10-2002, 06:53 PM
  5. Variables do not equal functions!!!
    By me@burk. in forum C Programming
    Replies: 3
    Last Post: 03-23-2002, 06:24 AM