By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
424,649 Members | 1,808 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 424,649 IT Pros & Developers. It's quick & easy.

No object definitions in header files?

P: n/a
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.

Nov 3 '06 #1
Share this Question
Share on Google+
36 Replies


P: n/a
zouyongbin wrote:
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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 3 '06 #2

P: n/a
"zouyongbin" writes:
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.
Nov 3 '06 #3

P: n/a

Victor Bazarov wrote:
zouyongbin wrote:
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.

Nov 3 '06 #4

P: n/a
zouyongbin wrote:
[..]
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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 3 '06 #5

P: n/a

osmium wrote:
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?

Nov 3 '06 #6

P: n/a
zouyongbin wrote:
osmium wrote:
>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?
The similarities between a class definition and an object definition
end at the use of the same term "definition".

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 3 '06 #7

P: n/a

Victor Bazarov wrote:
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?

Nov 3 '06 #8

P: n/a
zouyongbin wrote:
Victor Bazarov wrote:
>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?
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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 3 '06 #9

P: n/a

Victor Bazarov wrote:
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.

Nov 3 '06 #10

P: n/a

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

Nov 3 '06 #11

P: n/a

osmium wrote:
"zouyongbin" writes:
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.
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".

Nov 3 '06 #12

P: n/a
Salt_Peter wrote:
[..] 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
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 3 '06 #13

P: n/a
zouyongbin wrote:
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.

----== Posted via Newsfeeds.Com - Unlimited-Unrestricted-Secure Usenet News==----
http://www.newsfeeds.com The #1 Newsgroup Service in the World! 120,000+ Newsgroups
----= East and West-Coast Server Farms - Total Privacy via Encryption =----
Nov 3 '06 #14

P: n/a
zouyongbin wrote:
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.
Nov 3 '06 #15

P: n/a

Victor Bazarov wrote:
Salt_Peter wrote:
[..] 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.

Nov 3 '06 #16

P: n/a
zouyongbin wrote:
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.

--
Best regards,
Andrey Tarasevich
Nov 3 '06 #17

P: n/a
zouyongbin wrote:
...
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.
Nov 3 '06 #18

P: n/a
* 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: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 3 '06 #19

P: n/a
* Andrey Tarasevich:
zouyongbin wrote:
>...
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
Unless those objects are static members of some template class.

and non-inline
functions with external linkage. With everything else it is OK.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 3 '06 #20

P: n/a
Alf P. Steinbach wrote:
* Andrey Tarasevich:
>zouyongbin wrote:
>>...
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

Unless those objects are static members of some template class.
But then they are not objects but only object templates. Remember,
a member of a class template *is* a template.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Nov 3 '06 #21

P: n/a
"zouyongbin" <zo********@gmail.comwrote:
Stanley B Lippman in his "C++ Primer" that a definition like this
should not appear in a header file:

int ix;
Correct.
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.
All true.
And we can use "#ifndef" to eliminate the linker error complaining
about multiple definitions.
Not correct. The use of include guards is not to eliminate linker
errors, it is to eliminate compiler errors.
Do you agree with Mr Lippman?
Yes, I agree with Mr. Lippman.
I thought that the definition of a object is the same with the
definition of a class for header files.
No, the definition of an object is not the same as a definition of a
class. As long as all the class definitions are alike, multiple
definitions of a class will not cause a linker error, whereas multiple
definitions of an object will.

This really ought to be an FAQ:

"""
As a rule of thumb, a header may contain:
Named namespaces
namespace N { /*...*/ }
Type definitions
struct Point { int x, y; };
Template declarations
template<class Tclass Z;
Template definitions
template<class Tclass V { /* ... */ };
Function declarations
extern int strlen(const char*);
Inline function definitions
inline char get(char* p) { return *p++; }
Data declarations
extern int a;
Constant definitions
const float pi = 3.141593;
Enumerations
enum Light { red, yellow, green };
Name declarations
class Matrix;
Include directives
#include <algorithm>
Macro definitions
#define VERSION 12
Conditional compilation directives
#ifdef __cplusplus
Comments
/* check for end of file */

....

Conversely, a header should never contain:
Ordinary function definitions
char get(char* p) { return *p++; }
Data definitions
int a;
Aggregate definitions
short tbl[] = { 1, 2, 3 };
Unnamed namespaces
namespace { /* ... */ }
Exported template definitions
export template<class Tf(T t) { /* ... */ }
"""
--The C++ Programming Language 3rd Ed., Bjarne Stroustrup, section 9.2.1

To that second list one should add using declarations and directives.
using namespace foo;
using foo::bar;

--C++ Coding Standards, Herb Sutter &al,

--
To send me email, put "sheltie" in the subject.
Nov 4 '06 #22

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

int ix;
That is a guideline, not a rule. Guidelines can be broken.

Firstly, a static definition can certainly appear in a header.

static int x = 3;

This will create a private x in every translation unit that includes
it.

Secondly, you can use careful #if or #ifdef guards to ensure that the
one definition rule is observed, even if you have external definitions
in header files.

This can be exploited as follows:

// A.h
#ifndef A_H_34DF_C91B
#define A_H_34DF_C91B

class A {
...
};

#ifdef GENERATE_DEFS
A global_instance_a;
#else
extern A global_instance_a;
#endif

#endif

#endif
// End of A.h

// B.h
#ifndef B_H_37D0_1031
#define B_H_37D0_1031

#include "A.h"

class B {
... uses class A in some way
};

#ifdef GENERATE_DEFS
B global_instance_b(global_instance_a);
#else
extern B global_instance_b;
#endif

// End of B.h

Here we have two headers, A.h and B.h. They respectively define classes
A and B. Normally, the GENERATE_DEFS symbol is not defined and so the
headers provide an external declaration for objects global_instance_a
and global_instance_b.

The global_instance_b object knows about global_instance_a; it uses it,
and therefore global_instance_a must be initialized before
global_instance_b.

You create some source file where you do this:

#define GENERATE_DEFS
#include "B.h"

Now this becomes a translation unit in which all of the dependent
definitions appear, and in a sequence which ensures their correct
initialization order.
But as we know, the definition of a class is always in a
header file.
No, that is a class declaration, not a definition.
And we can use "#ifndef" to eliminate the linker error
complaining about multiple definitions.
No, the #ifdef eliminates multiple declarations of the same class in
the same translation unit. It does not prevent different translation
units from including that class.

This is different from the restriction on an external definition, which
must be made in exactly one place in the entire program.

The way many C++ implementations work internally, a duplicate class
declaration in the same translation unit is caught and diagnosed by the
compiler. Duplicate external definitions made in separate translation
units are caught by the linker.

You can actually have multiple declarations of an object in the same
(file) scope, but only one definition. E.g.

int x;
extern int x;
int x;
int x = 3;

This is a valid translation unit.

You can also have multiple declarations of a class, albeit only one of
them can provide a body, e.g:

class A;

class A {
...
};

Nov 4 '06 #23

P: n/a
* Victor Bazarov:
Alf P. Steinbach wrote:
>* Andrey Tarasevich:
>>zouyongbin wrote:
...
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
Unless those objects are static members of some template class.

But then they are not objects but only object templates. Remember,
a member of a class template *is* a template.
Well, no.

E.g., think about the header

template< Dummy_ >
struct Snark_ { static double globalTemperature; };

template< Dummy_ >
double Snark_<Dummy_>::globalTemperature = 3.333;

typedef Snark_<voidSnark; // External linkage.

double const tempSnapshot
= Snark::globalTemperature; // Internal linkage, using above.

Here Snark::globalTemperature is an external linkage variable of type
double defined in the header.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 4 '06 #24

P: n/a

Daniel T. wrote:

"what can go into a header file?"
This really ought to be an FAQ:

Yo are right. It is a frequently asked question, so it should be in
FAQs.

...
Conversely, a header should never contain:
Ordinary function definitions
char get(char* p) { return *p++; }
Data definitions
int a;
Aggregate definitions
short tbl[] = { 1, 2, 3 };
Unnamed namespaces
namespace { /* ... */ }
Exported template definitions
export template<class Tf(T t) { /* ... */ }
"""
--The C++ Programming Language 3rd Ed., Bjarne Stroustrup, section 9.2.1

To that second list one should add using declarations and directives.
using namespace foo;
using foo::bar;
I think that using declarations are often suitable in a header, to
selectively make names available. However, putting a using directive in
a header is as stated) most likely going to cause problems because it
would include an unbounded set of names (that would change and could
cause problems if the namespace later changed).

-- Bjarne Stroustrup; http://www.research.att.com/~bs

Nov 4 '06 #25

P: n/a
* Daniel T.:
"zouyongbin" <zo********@gmail.comwrote:
>Stanley B Lippman in his "C++ Primer" that a definition like this
should not appear in a header file:

int ix;

Correct.
Are you sure that Stanley really wrote that? Do you have a quote?

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

All true.
You mean, all false.

Cheers,

- Alf

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 4 '06 #26

P: n/a
"Alf P. Steinbach" <al***@start.nowrote:
* Daniel T.:
>"zouyongbin" <zo********@gmail.comwrote:
>>Stanley B Lippman in his "C++ Primer" that a definition like this
should not appear in a header file:

int ix;

Correct.

Are you sure that Stanley really wrote that? Do you have a quote?
I'm not sure if Mr. Lippman said it or not, but the statement is
non-the-less correct. Data definitions should not be put in header files
per Stroustrup (I've already posted the quote for that, but you snipped
it.)
>>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.

All true.

You mean, all false.
Hmm, it is true that multiple inclusions of data definitions will cause
a linker error complaining about multiple definitions. (The OP's first
sentence above.) It is true that this kind of definition should be
avoided in header files. (The OP's second sentence above.) And though
the definition of a class (what Stroustrup calls a "type definition" in
the quote I posted,) isn't *always* in a header file, it often is.

So each individual statement are basically true, AFAICT.

--
To send me email, put "sheltie" in the subject.
Nov 4 '06 #27

P: n/a
"bjarne" <bj****@gmail.comwrote:
Daniel T. wrote:
>To that second list one should add using declarations and
directives.
using namespace foo;
using foo::bar;

I think that using declarations are often suitable in a header, to
selectively make names available. However, putting a using directive
in a header is as stated) most likely going to cause problems
because it would include an unbounded set of names (that would
change and could cause problems if the namespace later changed).
Though I'm antsy to contradict you, I will quote Sutter and Alexandrescu:

Many people think that using declarations issued at namespace
level (for example, using N::Widget;) are safe. They are not. They
are at least as dangerous, and in a subtler and more insidious
way. Consider:

// snippet 1
namespace A {
int f(double);
}

// snippet 2
namespace B {
using A::f;
void g();
}

// snippet 3
namespace A {
int f(int);
}

// snippet 4
void B::g() {
f(1); // which overload is called?
}

... So, from within B, which overloads are visible depends on
where these code snippets exist and in what order they are
combined.

--
To send me email, put "sheltie" in the subject.
Nov 4 '06 #28

P: n/a
* Daniel T.:
"Alf P. Steinbach" <al***@start.nowrote:
>* Daniel T.:
>>"zouyongbin" <zo********@gmail.comwrote:

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

int ix;
Correct.
Are you sure that Stanley really wrote that? Do you have a quote?

I'm not sure if Mr. Lippman said it or not, but the statement is
non-the-less correct. Data definitions should not be put in header files
per Stroustrup (I've already posted the quote for that, but you snipped
it.)
Yes, Bjarne wrote a list of rules-of-thumb.

Those are good rules for newbies, or rules of thumb for newbies.

The OP's statement is a bit more absolute regarding where it applies
(namely universally in header files), and a bit more vague about what it
applies to, and is therefore highly questionable.

>>>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.
All true.
You mean, all false.

Hmm, it is true that multiple inclusions of data definitions will cause
a linker error complaining about multiple definitions. (The OP's first
sentence above.)
The OP's statement quoted right above is false. In particular the
definition 'int i;' is extremely common, and may occur thousands or tens
of thousands of times in a large application. No ill effect as long as
those are not definitions of the same name denoting the same kind of
thing in the same namespace.

Your statement is even more false, if that is possible.

I've illustrated elsethread one way to do direct variable definitions at
namespace scope properly in a header file (just insert missing
'typename' keywords in that code), so that the header file can be safely
included in any number of translation units. By that example, it's
false that multiple inclusions of data definitions from a header file
will necessarily cause any kind of error in a conforming C++
implementation. If your compiler or linker complains for that example,
then it's not standard-conforming.

It is true that this kind of definition should be
avoided in header files. (The OP's second sentence above.)
First, it's not true that the kind of definition illustrated should be
avoided in a header file. But it's a good idea to avoid it at namespace
scope. Second, it's not true that that was the OP's second sentence,
and it's not true that your paraphrasing above was the OP's second sentence.

And though
the definition of a class (what Stroustrup calls a "type definition" in
the quote I posted,) isn't *always* in a header file, it often is.
Good that you admit that your "all true" isn't true after all.

So each individual statement are basically true, AFAICT.
But this leap of logic is beyond me.
--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 4 '06 #29

P: n/a
"Alf P. Steinbach" <al***@start.nowrote:
* Daniel T.:
>"Alf P. Steinbach" <al***@start.nowrote:
>>* Daniel T.:
"zouyongbin" <zo********@gmail.comwrote:

Stanley B Lippman in his "C++ Primer" that a definition like
this should not appear in a header file:
>
int ix;
Correct.
Are you sure that Stanley really wrote that? Do you have a quote?

I'm not sure if Mr. Lippman said it or not, but the statement is
non-the-less correct. Data definitions should not be put in header
files per Stroustrup (I've already posted the quote for that, but
you snipped it.)

Yes, Bjarne wrote a list of rules-of-thumb.

Those are good rules for newbies, or rules of thumb for newbies.

The OP's statement is a bit more absolute regarding where it applies
(namely universally in header files), and a bit more vague about
what it applies to, and is therefore highly questionable.
It seems pretty spicific as to what it applies to. It applies to putting
data definitions (i.e., "int i;") at global or namespace scope in header
files that are included in multiple translations units. I'm willing to
say that I may be reading more into it.
>>>>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.
All true.
You mean, all false.

Hmm, it is true that multiple inclusions of data definitions will
cause a linker error complaining about multiple definitions. (The
OP's first sentence above.)

The OP's statement quoted right above is false. In particular the
definition 'int i;' is extremely common, and may occur thousands or tens
of thousands of times in a large application. No ill effect as long as
those are not definitions of the same name denoting the same kind of
thing in the same namespace.
OK, I see the disconnect now. You are assuming that the OP is
questioning putting "int i;" *anywhere* in a header file. I didn't think
the OP was trying to make that blanket of a statement. It seemed to me
he was more confused as to why a data definition should not be put at
the global or namespace scope of a .h file whereas newbies are
encouraged to put a class definition at the same scope in the .h file.
I've illustrated elsethread one way to do direct variable
definitions at namespace scope properly in a header file (just
insert missing 'typename' keywords in that code), so that the header
file can be safely included in any number of translation units.
The only example I noticed was the Dummy Snark example and it didn't
have any data definitions in it. It did have a constant defintion in it
(which Stroustrup puts on the list of things that can safely go in
header files.) The OP wasn't talking about constant definitions.

--
To send me email, put "sheltie" in the subject.
Nov 4 '06 #30

P: n/a
* Daniel T.:
>
>I've illustrated elsethread one way to do direct variable
definitions at namespace scope properly in a header file (just
insert missing 'typename' keywords in that code), so that the header
file can be safely included in any number of translation units.

The only example I noticed was the Dummy Snark example and it didn't
have any data definitions in it. It did have a constant defintion in it
(which Stroustrup puts on the list of things that can safely go in
header files.) The OP wasn't talking about constant definitions.
Note that Snark::globalTemperature is an extern linkage /non-constant/
variable, defined and initialized to a specific value in the header
file, where that header file can be included in any number of
translation units without ill effects.

OK, there was a typo in that off-the-cuff example (missing 'typename'),
and also a typo in the paragraph you quoted above (the variable is not
directly at namespace scope, but is still a global), and the reason I
defined a non-const variable was just to show it could be done: it's
generally Very UnGood to define global non-const variables.

But repeating such a non-const variable definition in different
translation units in the way I showed, does absolutely not require any
linker error or other diagnostic as you maintained it must: it's
standard C++ which a conforming implementation must accept.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 4 '06 #31

P: n/a
Daniel T. wrote:
...
This really ought to be an FAQ:
...
--The C++ Programming Language 3rd Ed., Bjarne Stroustrup, section 9.2.1
...
Bjarne Stroustrup's books are often aimed at beginners and as such, they
often took certain liberties with C++ terminology for the sake of
simplicity. This group nomally prefers to stick to the official
terminology used in the language standard. That applies to the FAQ as
well, which means that the quote you provided is not really ready to be
placed in the FAQ just yet.

--
Best regards,
Andrey Tarasevich

Nov 4 '06 #32

P: n/a
Daniel T. wrote:
"bjarne" <bj****@gmail.comwrote:
>Daniel T. wrote:
>>To that second list one should add using declarations and
directives.
using namespace foo;
using foo::bar;

I think that using declarations are often suitable in a header, to
selectively make names available. However, putting a using directive
in a header is as stated) most likely going to cause problems
because it would include an unbounded set of names (that would
change and could cause problems if the namespace later changed).

Though I'm antsy to contradict you, I will quote Sutter and Alexandrescu:

Many people think that using declarations issued at namespace
level (for example, using N::Widget;) are safe. They are not. They
are at least as dangerous, and in a subtler and more insidious
way.
...
Sorry, but that's not convincing enough to serve as an argument against
placing such declarations in header files. There's a huge difference
between something being "safe" and something being "practically useful".
After all, there nothing in C++ that's absolutely "safe".

--
Best regards,
Andrey Tarasevich

Nov 4 '06 #33

P: n/a
Andrey Tarasevich <an**************@hotmail.comwrote:
Daniel T. wrote:
>"bjarne" <bj****@gmail.comwrote:
>>Daniel T. wrote:

To that second list one should add using declarations and
directives. using namespace foo; using foo::bar;

I think that using declarations are often suitable in a header, to
selectively make names available. However, putting a using
directive in a header is as stated) most likely going to cause
problems because it would include an unbounded set of names (that
would change and could cause problems if the namespace later
changed).

Though I'm antsy to contradict you, I will quote Sutter and
Alexandrescu:

Many people think that using declarations issued at namespace
level (for example, using N::Widget;) are safe. They are not.
They are at least as dangerous, and in a subtler and more
insidious way. ...

Sorry, but that's not convincing enough to serve as an argument
against placing such declarations in header files. There's a huge
difference between something being "safe" and something being
"practically useful". After all, there nothing in C++ that's
absolutely "safe".
Well, since it is not my argument I don't think I will carry it any
further. For my own part, I find that code which depends on order of
compilation is harder to understand and maintain, so I will continue to
avoid such code.

--
To send me email, put "sheltie" in the subject.
Nov 4 '06 #34

P: n/a
Kaz Kylheku wrote:
<snip>
>
You can actually have multiple declarations of an object in the same
(file) scope, but only one definition. E.g.

int x;
extern int x;
int x;
int x = 3;

This is a valid translation unit.
I know above is valid C. But C++? Can you please provide the C&V.

Krishanu
Nov 6 '06 #35

P: n/a
Krishanu Debnath wrote:
Kaz Kylheku wrote:
<snip>

You can actually have multiple declarations of an object in the same
(file) scope, but only one definition. E.g.

int x;
extern int x;
int x;
int x = 3;

This is a valid translation unit.

I know above is valid C. But C++? Can you please provide the C&V.
The statement is mostly correct - a single variable may appear any
number of times in an (extern) variable declaration but only once in a
variable definition. The example, however, shows exactly the opposite:
three definitions of an x variable and only one x extern declaration.

So swapping the x declaration with the x definitions does create an
example of legal C++:

extern int x;
int x;
extern int x;
extern int x;

Greg

Nov 6 '06 #36

P: n/a
Alf P. Steinbach wrote:
>>>...
The second kind of multiple definition is illegal with objects
Unless those objects are static members of some template class.

But then they are not objects but only object templates. Remember,
a member of a class template *is* a template.

Well, no.

E.g., think about the header

template< Dummy_ >
struct Snark_ { static double globalTemperature; };

template< Dummy_ >
double Snark_<Dummy_>::globalTemperature = 3.333;

typedef Snark_<voidSnark; // External linkage.

double const tempSnapshot
= Snark::globalTemperature; // Internal linkage, using above.

Here Snark::globalTemperature is an external linkage variable of type
double defined in the header.
...
Not really. (The 'typedef' does not really add anything - it's just a piece of
syntactic sugar that doesn't cause the instantiation of the template, so we can
get rid of it without changing the effect of this example.) What we really have is

double const tempSnapshot = Snark_<void>::globalTemperature;

The initializer expression in this case in a _specialization_ of a template.
This specialization is used in a context that will cause the data member
template to be _implicitly_ _instantiated_. That instantiation is what turns the
data member template into an actual (i.e. storage-occupying) object. In C++
terminology, 'implicit instantiation' is a process different from 'definition',
even though they have certain similarities. 'Definition' is something the user
explicitly does himself. 'Implicit instantiation' is something the compiler does
behind the scenes. Even though this implicit instantiation will "materialize"
this data member, it is still not correct to assume that it works "as-if" this
'definition' occurs specifically in this header file.

If you wanted to perform instantiation of that data member that is indeed very
similar to definition, you'd have to do an _explicit_ instantiation

template double Snarl_<void>::globalTemperature; // explicit instantiation

The effect of the above is indeed a close equivalent of 'defining' a static data
member of a class template. But if done in a header file, this will (not
surprisingly) lead to multiple-definition error, just like an object definition
would.

--
Best regards,
Andrey Tarasevich

P.S. BTW, your example, if fact, is similar to this:

template< typename Dummy_ >
struct Snark_ { static void foo(); };

template< typename Dummy_ >
void Snark_<Dummy_>::foo() {} // external linkage

static void bar() // internal linkage
{ Snark_<void>::foo(); }

According to your logic, in this case we also have a definition of static
function 'Snark_<void>::foo' with external linkage in header file. So,
technically you had to include static member functions in your "unless"
statement as well.
Nov 6 '06 #37

This discussion thread is closed

Replies have been disabled for this discussion.