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

non static variables in a namespace (in .h) ?

P: n/a
Hi,

Sorry for the bad subject, but i couldn't figure a better one.

I would like to understand why a variable declared non static in a
header causes multiple symbol definitions (if included in different
compilation units) while the same declaration in a namespace does not.

Also, what is the correct way to declare a scoped variable in a
header ? Using extern and declaring it in a separate compilation
unit ?

Thank you,
Vincent

Mar 7 '07 #1
Share this Question
Share on Google+
9 Replies


P: n/a
vt********@gmail.com wrote:
Hi,

Sorry for the bad subject, but i couldn't figure a better one.

I would like to understand why a variable declared non static in a
header causes multiple symbol definitions (if included in different
compilation units) while the same declaration in a namespace does not.
Could you show me an example, cause if you define a variable twice in
the same namespace, you should get multiple symbol definitions and
linker errors.

Did you mean you can define the same variable in different namespaces?
That's fine, of course.
>
Also, what is the correct way to declare a scoped variable in a
header ? Using extern and declaring it in a separate compilation
unit ?
If you have to put the definition in a namespace in a header included in
multiple compilation units, then you should declare it extern and define
it in a single compilation unit.

ex:

myhdr.hh

#ifndef MYHDR_HH_
#define MYHDR_HH_

namespace myns {
extern int myvar;
}

#endif

main.cc

#include "myhdr.hh"

int myns::myvar;

int main() {
myns::myvar = 6;
}

aux.cc

#include "myhdr.hh"

void myfcn() {
myns::myvar = 10;
}

--John Ratliff
Mar 7 '07 #2

P: n/a
vt********@gmail.com wrote:
Sorry for the bad subject, but i couldn't figure a better one.

I would like to understand why a variable declared non static in a
header causes multiple symbol definitions (if included in different
compilation units) while the same declaration in a namespace does not.
I don't believe that the second part of this statement is correct.
Are you sure about "the same declaration"?

Anyway, an object that is not const and is not explicitly declared
'static' has _external_ linkage, IOW its name is visible from other
translation units. If you define (if the declaration does not have
'extern' specifier, it's a definition) objects with the same name
in more than one translation unit, it's a violation of the ODR. You
usually get the error from the linker who is the last to check the
ODR when linking different TUs together.

If you declare the object 'static', its name is hidden from other TU
(not extern), the term is that the name has _internal_ linkage. That
way you can have objects named the same in different TUs.
Also, what is the correct way to declare a scoped variable in a
header ?
"Scoped"? What does that mean? Any variable is scoped, IOW every
variable has its scope.
Using extern and declaring it in a separate compilation
unit ?
There are variations on the theme, but they all essentially lead to
the same: declaration is available in every TU, and the definition
exist only in one TU.

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

P: n/a
John Ratliff wrote:
vt********@gmail.com wrote:
>Hi,

Sorry for the bad subject, but i couldn't figure a better one.

I would like to understand why a variable declared non static in a
header causes multiple symbol definitions (if included in different
compilation units) while the same declaration in a namespace does
not.

Could you show me an example, cause if you define a variable twice in
the same namespace, you should get multiple symbol definitions and
linker errors.

Did you mean you can define the same variable in different namespaces?
That's fine, of course.
I just thought of what it could be: anonymous namespaces. But that
falls under "different" category, of course, only the OP didn't think
of it that way, most likely.
[..]
V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Mar 7 '07 #4

P: n/a
On 7 mar, 19:49, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
vthomas...@gmail.com wrote:
I would like to understand why a variable declared non static in a
header causes multiple symbol definitions (if included in different
compilation units) while the same declaration in a namespace does not.

I don't believe that the second part of this statement is correct.
Are you sure about "the same declaration"?
My example comes from some software i use. In the main include file,
it declares a
bunch of strings as in the following:

namespace x {
const std::string s1 = "txt1";
const std::string s2 = "txt2";
}

and the software compiles and runs just fine. When i saw this it
struck as being strange (that it didn't cause link time error), so i
just added a simple test string declaration outside of the namespace
and, of course, got a bunch of 'redeclared symbol' messages at link
time.
Anyway, an object that is not const and is not explicitly declared
'static' has _external_ linkage, IOW its name is visible from other
translation units. If you define (if the declaration does not have
'extern' specifier, it's a definition) objects with the same name
in more than one translation unit, it's a violation of the ODR. You
usually get the error from the linker who is the last to check the
ODR when linking different TUs together.
These strings are const. Does it make any difference ?
"Scoped"? What does that mean? Any variable is scoped, IOW every
variable has its scope.
I meant in a namespace... sorry.
There are variations on the theme, but they all essentially lead to
the same: declaration is available in every TU, and the definition
exist only in one TU.
OK, so being in a namespace does not change the linkage type in any
way ?

Vincent

Mar 7 '07 #5

P: n/a
On 7 mar, 19:48, John Ratliff <u...@example.netwrote:
vthomas...@gmail.com wrote:
Could you show me an example, cause if you define a variable twice in
the same namespace, you should get multiple symbol definitions and
linker errors.
See my response to Victor Bazarow. I can give a link to the header
file on source control if you would like to see the real code, but
it's really as plain as i said (though the variables are const).
Did you mean you can define the same variable in different namespaces?
That's fine, of course.
No, i meant in the same namespace.
If you have to put the definition in a namespace in a header included in
multiple compilation units, then you should declare it extern and define
it in a single compilation unit.
<snip example code>

OK, this is how i understand it, so i don't understand why it works
correctly in this other software.

Vincent

Mar 7 '07 #6

P: n/a
vt********@gmail.com wrote:
On 7 mar, 19:49, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
>vthomas...@gmail.com wrote:
>>I would like to understand why a variable declared non static in a
header causes multiple symbol definitions (if included in different
compilation units) while the same declaration in a namespace does
not.

I don't believe that the second part of this statement is correct.
Are you sure about "the same declaration"?

My example comes from some software i use. In the main include file,
it declares a
bunch of strings as in the following:

namespace x {
const std::string s1 = "txt1";
const std::string s2 = "txt2";
}
So, have you tried doing the same without the namespace? Does it
make an iota of difference (except for the s1 and s2 name lookup)?
and the software compiles and runs just fine. When i saw this it
struck as being strange (that it didn't cause link time error), so i
just added a simple test string declaration outside of the namespace
and, of course, got a bunch of 'redeclared symbol' messages at link
time.
Nothing strange. Objects are 'const', they have internal linkage.
>
>Anyway, an object that is not const and is not explicitly declared
'static' has _external_ linkage, IOW its name is visible from other
translation units. If you define (if the declaration does not have
'extern' specifier, it's a definition) objects with the same name
in more than one translation unit, it's a violation of the ODR. You
usually get the error from the linker who is the last to check the
ODR when linking different TUs together.

These strings are const. Does it make any difference ?
Absodamnlutely.
>"Scoped"? What does that mean? Any variable is scoped, IOW every
variable has its scope.

I meant in a namespace... sorry.
Well, those that are "not in a namespace" are actually *in* the
_global_ namespace. The prefix for finding those is '::'. E.g.

int a = 0;
int main() {
double a = 3.14159;
return ::a; // note the ::
}

There are two 'a' objects here, one has global namespace scope,
the other has 'main' function scope.
>There are variations on the theme, but they all essentially lead to
the same: declaration is available in every TU, and the definition
exist only in one TU.

OK, so being in a namespace does not change the linkage type in any
way ?
Nope.

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

P: n/a
On 7 mar, 20:18, vthomas...@gmail.com wrote:
and the software compiles and runs just fine. When i saw this it
struck as being strange (that it didn't cause link time error), so i
just added a simple test string declaration outside of the namespace
and, of course, got a bunch of 'redeclared symbol' messages at link
time.
Hmmm, sorry, i just realized that i declared a non const string
outside
the namespace (which caused the error). If declared const, i don't get
a linking error, so it appears my question is actually about the const
keyword rather than on being in a namespace.

Mar 7 '07 #8

P: n/a
vt********@gmail.com wrote:
On 7 mar, 20:18, vthomas...@gmail.com wrote:
>and the software compiles and runs just fine. When i saw this it
struck as being strange (that it didn't cause link time error), so i
just added a simple test string declaration outside of the namespace
and, of course, got a bunch of 'redeclared symbol' messages at link
time.

Hmmm, sorry, i just realized that i declared a non const string
outside
the namespace (which caused the error). If declared const, i don't get
a linking error, so it appears my question is actually about the const
keyword rather than on being in a namespace.
Yep. 'const' without "extern" gives the object internal linkage.

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

P: n/a
On 7 mar, 20:47, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
vthomas...@gmail.com wrote:
namespace x {
const std::string s1 = "txt1";
const std::string s2 = "txt2";
}

So, have you tried doing the same without the namespace? Does it
make an iota of difference (except for the s1 and s2 name lookup)?
I have now. :-)
Nothing strange. Objects are 'const', they have internal linkage.
Thanks a lot for your explanations.

Vincent
Mar 7 '07 #10

This discussion thread is closed

Replies have been disabled for this discussion.