No object definitions in header files?

Discussion in 'C++' started by zouyongbin, Nov 3, 2006.

  1. zouyongbin

    zouyongbin Guest

    Stanley B Lippman in his "C++ Primer" that a definition like this
    should not appear in a header file:

    int ix;

    The inclusion of any of these definitions in two or more files of the
    same program will result in a linker error complaining about multiple
    definitions. So this kind of definition should be avoided as much as
    possible. But as we know, the definition of a class is always in a
    header file. And we can use "#ifndef" to eliminate the linker error
    complaining about multiple definitions.

    Do you agree with Mr Lippman? I thought that the definition of a object
    is the same with the definition of a class for header files. Multiple
    definitions will cause error for both of them.
    zouyongbin, Nov 3, 2006
    1. Advertisements

  2. You don't have to agree. Just try it yourself.
    No. What we know as "class definitions" consist only of declarations
    and definitions of inline functions. All perfectly legal if appear
    multiple times in a program. Object definitions are different.

    Victor Bazarov, Nov 3, 2006
    1. Advertisements

  3. zouyongbin

    osmium Guest

    Your belief is kind of natural and is a result of C++ blurring or obscuring
    the distinction between types and variables. A class definition is the
    definition of a *type*, not a variable. Yes, he's right.
    osmium, Nov 3, 2006
  4. zouyongbin

    zouyongbin Guest

    Declarations and definitions of inline functions can appear multiple
    times in a program without causing errors. That's true. But what if the
    class definition as a whole appear multiple times? I thought that that
    will cause error.

    BTW, I always think that declarations should be put into header files,
    and definitions should be put into source files. But the fact that we
    are used to put class definitions into header files made me confused.
    zouyongbin, Nov 3, 2006
  5. I think you're overthinking it. Inclusion of header files puts *all*
    the header contains in the source files. Now, you control how many
    times it's there. And as 'osmium' noted, you're confusing objects and

    Victor Bazarov, Nov 3, 2006
  6. zouyongbin

    zouyongbin Guest

    Sorry. I think I didn't make myself clear. I was not saying that a
    class definition IS the definition of a variable. I meant that there
    are some similarities between a class definition and the definition of
    a variable: they can not be multiple defined. So if we can put class
    definitions into header files, why not object definitions?
    zouyongbin, Nov 3, 2006
  7. The similarities between a class definition and an object definition
    end at the use of the same term "definition".

    Victor Bazarov, Nov 3, 2006
  8. zouyongbin

    zouyongbin Guest

    Hehe. Then do you think that defining objects in header files is
    zouyongbin, Nov 3, 2006
  9. Yes, as long as you only include that header file in one source file.

    Have you been reading what I posted in this thread at all?

    Victor Bazarov, Nov 3, 2006
  10. zouyongbin

    zouyongbin Guest

    Yes, I did. Just wanna a confirmation.
    Thanks so much for your great help, Victor.
    zouyongbin, Nov 3, 2006
  11. zouyongbin

    Salt_Peter Guest

    By definition here he means an instance of an integer, as opposed to
    the implementation of a type.
    See if you can differentiate declaration and implementation from
    definition. You can mix the declaration and implementation safely, you
    can also mix implementation and definitions. What you can't do is mix
    declarations and definitions.

    The implementation of a class is not always in a header. The
    declaration usually is (include guards prevent multiple declarations).
    The implementation of a class is often found in an implementation file
    (*.cpp). That type implementation does not create an object of the
    type, it just implements the declared "blueprint" of the type. So there
    a) type declarations (*.h or *.hpp)
    b) type implementations (*.cpp)
    c) instances of the above (or definitions) (in various cpp files)

    // header a.h
    class A
    int n; // declares an integer member, not an instance, so thats ok
    }; // declares a blueprint

    // test.cpp
    #include "a.h"
    int ix; // is an instance of an integer
    A a; // is an instance of type A, which has an instance of member n
    Yes to agree.
    No, the declaration and/or implementation of a type is not an instance.
    Hopefully, somebody has better skills to explain the difference to you.

    If you write...
    int ix = 0;
    ....*outside* of the class declaration *in* the header file, the
    compiler attempts to define/allocate an integer.
    Thats what Mr Lippman is referring to.

    // header A.h
    #ifndef A_H_
    #define A_H_

    class A
    int n; // ok, part of the type declaration, not a definition
    }; // a declaration

    int ix = 0; // bad, an independant instance, potentially defined
    multiple times.


    I'm sorry if i'm confusing you.
    declaration/implementation != definition
    Geez, i almost sound like i'm trying to convince myself.
    Salt_Peter, Nov 3, 2006
  12. zouyongbin

    Salt_Peter Guest

    Both you and Victor are pursuing an honourable discussion.
    Like it or not, the OP is bound to come accross the gray area between
    the definition of a type and the definition of a variable in the real
    But you have to admit that it would be beneficial to talk about
    implementation of a type and definition of an object in order to keep
    the OP on focus. When i hear "definition of a type", i also see the
    making of an object, not its implementation.
    Anyway, my goal is not to start a war or a lengthy arguement, i'm just
    curious as to what you guys see in "definition of a type".
    Salt_Peter, Nov 3, 2006
  13. A definition of a type is [as opposed to a declaration of a type]
    is a detailed description of what the [an instance of that] type
    consists of and how [an instance of] the type behaves.

    A definition of an object is [as opposed to a declaration of
    an object] an instruction to the compiler to generate code to
    allocate memory for that object.

    Victor Bazarov, Nov 3, 2006
  14. zouyongbin

    Mark P Guest

    Include guards (#ifndef blocks) are for the benefit of the compiler, not
    the linker. They ensure that the same code does not appear twice in the
    same translation unit. The linker sees the compiled object files and
    should never encounter these preprocessor commads.
    Mark P, Nov 3, 2006
  15. Please quote chapter and verse.
    The problem with C and C++ is that
    they include no formal way to define "module interfaces".
    C and C++ programmers use header files
    to overcome this deficiency.
    A [module} interface has no substance.
    It must not by itself cause the compiler
    to emit code or reserve memory for objects.
    C preprocessor macro definitions and inline function definitions
    are allowed in module interfaces because the don't require the compiler
    to emit any code until they are actually invoked.
    const object definitions are allowed in C++ but not in C.
    Variables may be declared but not defined in C and C++ module interfaces.
    E. Robert Tisdale, Nov 3, 2006
  16. zouyongbin

    Salt_Peter Guest

    Thank-you Victor. Thats very clear.
    Salt_Peter, Nov 3, 2006
  17. That's correct. One can add that the above applies specifically to definitions
    of objects with _external_ linkage.

    Objects with _internal_ linkage can be defined in header files. Each translation
    unit in this case will get it's own instance of that object. Whether (and when)
    this is useful (if at all) is a different story.

    The same can also be said about function definitions (functions are not
    objects). Functions with external linkage should not be defined in header files.
    Functions with internal linkage can be defined in header files. Also, inline
    functions can be defined in header files even if they have external linkage.
    Hmm... This "as much as possible" sounds rather strange in this context.
    Normally, a person that understands the idea behind C++ declarations and
    definitions will not even think about doing something like this. Which means
    that it won't be necessary to worry about this kind of "avoidance".
    Always? No. You can place class definition in implementation file, if it works
    for you.

    Yet it is true that class definitions can be (and most often are) placed in
    header files. It does not create any problems since classes are not objects and
    definition rules for classes are different from those for objects. The same
    applies to template definitions.
    Linker error? No. If you are talking about include guards (your '#ifdef'), then
    what they do is prevent multiple definitions of the same entity in the same
    translation unit. Such errors are usually caught by the compiler. Linker errors
    are normally caused by multiple definitions spread across several translation
    units. Include guards don't help to solve that latter problem at all.
    Of course.
    It is not.
    No. The rule you are looking for is caller One definition Rule (ODR). Look it up
    in the C++ standard or in some good book on C++. Actually, you can simply Goggle
    for it.
    Andrey Tarasevich, Nov 3, 2006
  18. There are two different "levels" of being "multiple defined" (MD) in C++. First
    is being multiple defined in the same translation unit. Second is being multiple
    defined across several translation units.

    The first kind of multiple definition is illegal with pretty much everything.
    One exception - typedef-names. Typedef-names can be defined multiple times in
    the same translations unit as long as all definitions are the same. (I won't
    mention "macro definitions" here).

    The second kind of multiple definition is illegal with objects and non-inline
    functions with external linkage. With everything else it is OK.

    Best regards,
    Andrey Tarasevich

    P.S. The include guards ('#ifdef' you mention in your first message) help
    avoiding the first kind of MD problems, and have nothing to do with the second one.
    Andrey Tarasevich, Nov 3, 2006
  19. * zouyongbin:
    Please, when you're attributing some statement to someone, /quote/.

    I don't know what Stanley wrote.

    But I'm pretty sure it's not what you wrote.

    On the other hand, there are things a newbie should not put in a header
    file, including:

    * "using namespace std;".

    * Simple declarations of variables, like the one above.

    * Non-inline function definitions.

    The rationale is that for the newbie, avoiding these things in header
    files can avoid a great many problems causes by inappropriate usage.

    About what? Quote Mr. Lippman if you're asking about something more
    concrete than your impressions.

    The language standard does not care whether a definition is in a zygloid
    file, a mariccalombi file, a snortell file, or whatever kind of file, or
    something else. It's all just text.

    Well, no, but it's a bit complicated, so I choose not to explain all
    that's relevant for the general case. If you have some specific code
    with some specific problem, please do post about that. But then only
    after first reading up on the FAQ item "How do I post a question about
    code that doesn't work correctly" (or something like that, I don't
    recall the exact title), and then following that advice in your posting.
    Alf P. Steinbach, Nov 3, 2006
  20. * Andrey Tarasevich:
    Unless those objects are static members of some template class.
    Alf P. Steinbach, Nov 3, 2006
    1. Advertisements

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.