No object definitions in header files?

Z

zouyongbin

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.
 
V

Victor Bazarov

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

int ix;
[..]
Do you agree with Mr Lippman?

You don't have to agree. Just try it yourself.
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.

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.

V
 
O

osmium

zouyongbin said:
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.

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.
 
Z

zouyongbin

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

int ix;
[..]
Do you agree with Mr Lippman?

You don't have to agree. Just try it yourself.
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.

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.

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.
 
V

Victor Bazarov

zouyongbin said:
[..]
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.

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
types.

V
 
Z

zouyongbin

osmium said:
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.

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?
 
V

Victor Bazarov

zouyongbin said:
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?

The similarities between a class definition and an object definition
end at the use of the same term "definition".

V
 
Z

zouyongbin

Victor said:
The similarities between a class definition and an object definition
end at the use of the same term "definition".

Hehe. Then do you think that defining objects in header files is
harmless?
 
V

Victor Bazarov

zouyongbin said:
Hehe. Then do you think that defining objects in header files is
harmless?

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?

V
 
Z

zouyongbin

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

Yes, I did. Just wanna a confirmation.
Thanks so much for your great help, Victor.
 
S

Salt_Peter

zouyongbin said:
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.

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
are:
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
....
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.

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.

#endif

I'm sorry if i'm confusing you.
declaration/implementation != definition
Geez, i almost sound like i'm trying to convince myself.
 
S

Salt_Peter

osmium said:
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.

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
world.
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".
 
V

Victor Bazarov

Salt_Peter said:
[..] i'm just
curious as to what you guys see in "definition of a type".

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.

V
 
M

Mark P

zouyongbin said:
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.

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.
 
E

E. Robert Tisdale

zouyongbin said:
Stanley B Lippman in his "C++ Primer"

Please quote chapter and verse.
that a definition like this

int ix;

should not appear in a header file:
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.

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.
 
S

Salt_Peter

Victor said:
Salt_Peter said:
[..] i'm just
curious as to what you guys see in "definition of a type".

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.

V
--

Thank-you Victor. Thats very clear.
 
A

Andrey Tarasevich

zouyongbin said:
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.

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.
So this kind of definition should be avoided as much as
possible.

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".
But as we know, the definition of a class is always in a
header file.

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.
And we can use "#ifndef" to eliminate the linker error
complaining about multiple 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.
Do you agree with Mr Lippman?

Of course.
I thought that the definition of a object
is the same with the definition of a class for header files.

It is not.
Multiple definitions will cause error for both of them.

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.
 
A

Andrey Tarasevich

zouyongbin said:
...
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?
...

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.
 
A

Alf P. Steinbach

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

int ix;

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.

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.
No.


So this kind of definition should be avoided as much as
possible.
No.


But as we know, the definition of a class is always in a
header file.
No.


And we can use "#ifndef" to eliminate the linker error
complaining about multiple definitions.
No.


Do you agree with Mr Lippman?

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

I thought that the definition of a object
is the same with the definition of a class for header files.

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.

Multiple
definitions will cause error for both of them.

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.
 
A

Alf P. Steinbach

* Andrey Tarasevich:
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

Unless those objects are static members of some template class.
 

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. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,236
Members
46,825
Latest member
VernonQuy6

Latest Threads

Top