473,386 Members | 1,702 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,386 software developers and data experts.

anonymous namespace and linkage

Hi everyone,

AFAIK external linkage allows you to refer to variables/functions
outside of the current translation unit. A variable in an unnamed
namespace is similar to declaring a static variable, but according to
the standard there is a difference:
"While this is essentially true in practical effect, there are subtle
differences. Using static as shown here causes "i" to have internal
linkage. When declared in an unnamed namespace without the use of
static, it has external linkage. This use of static is officially
deprecated (C++ Standard 7.3.1.1/2)."

To me this means that the variable is accessible outside of the
translation unit. However, Herb Schildt's book shows the following:
------------------------------------------------------------------------------------------
While the use of static global declarations is still allowed in C++, a
better way to
accomplish the same effect is to use an unnamed namespace. For
example:
File One
namespace {
int k;
}
void f1() {
k = 99; // OK
}

File Two
extern int k;
void f2() {
k = 10; // error
}
Here, k is also restricted to File One. The use of the unnamed
namespace rather than
static is recommended for new code.
------------------------------------------------------------------------------------------

So how is it that 'k' has external linkage?

Thanks

Taras
Sep 6 '08 #1
12 5366
Taras_96 wrote:
AFAIK external linkage allows you to refer to variables/functions
outside of the current translation unit. A variable in an unnamed
namespace is similar to declaring a static variable, but according to
the standard there is a difference:
"While this is essentially true in practical effect, there are subtle
differences. Using static as shown here causes "i" to have internal
linkage. When declared in an unnamed namespace without the use of
static, it has external linkage. This use of static is officially
deprecated (C++ Standard 7.3.1.1/2)."

To me this means that the variable is accessible outside of the
translation unit.
There is no way for the compiler to figure out the right name for the
variable when compiler *another* translation unit. That's the trick
to make it "not available". The name is made up unique while the
compiler is compiling that particular translation unit.
However, Herb Schildt's book shows the following:
Ugh! Yuck! I'm telling Mom! ...Mom, Taras said the "S" name, and
he is reading THAT book!...

Throw that book away, Taras, and get yourself a *real* C++ book.
Visit www.accu.org, the book review section, to see what are the
recommended titles.
[..]

So how is it that 'k' has external linkage?
It just does. The compiler provides it with external linkage.
What is the difference how it accomplishes that?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Sep 6 '08 #2
On Sep 6, 8:56 pm, Taras_96 <taras...@gmail.comwrote:
AFAIK external linkage allows you to refer to
variables/functions outside of the current translation unit. A
variable in an unnamed namespace is similar to declaring a
static variable, but according to the standard there is a
difference:
"While this is essentially true in practical effect, there are
subtle differences. Using static as shown here causes "i" to
have internal linkage. When declared in an unnamed namespace
without the use of static, it has external linkage. This use
of static is officially deprecated (C++ Standard 7.3.1.1/2)."
To me this means that the variable is accessible outside of
the translation unit. However, Herb Schildt's book shows the
following:
------------------------------------------------------------------------------------------
While the use of static global declarations is still allowed
in C++, a better way to accomplish the same effect is to use
an unnamed namespace. For example:
File One
namespace {
int k;}
void f1() {
k = 99; // OK
}
File Two
extern int k;
void f2() {
k = 10; // error}
Here, k is also restricted to File One. The use of the unnamed
namespace rather than static is recommended for new code.
------------------------------------------------------------------------------------------
So how is it that 'k' has external linkage?
It has external linkage, just like any other variable. In file
one, the definition is in a namespace with a name unique to the
file; in file 2, k is in global namespace. This is more or less
the same as if you had:

File One:
namespace TopSecrectName {
int k ;
}
using TopSecrectName ;
// ...

File Two
extern int k ;
// ...

Since the two k aren't in the same namespace, their qualified
names are different, and they can only be different entities.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 6 '08 #3
In article
<0c**********************************@j22g2000hsf. googlegroups.com>,
Taras_96 <ta******@gmail.comwrote:
AFAIK external linkage allows you to refer to variables/functions
outside of the current translation unit. A variable in an unnamed
namespace is similar to declaring a static variable, but according to
the standard there is a difference:

"While this is essentially true in practical effect, there are subtle
differences. Using static as shown here causes "i" to have internal
linkage. When declared in an unnamed namespace without the use of
static, it has external linkage. This use of static is officially
deprecated (C++ Standard 7.3.1.1/2)."

To me this means that the variable is accessible outside of the
translation unit. [...]
External linkage has other useful consequences as well. The first that
comes to mind is that the unnamed namespace allows templates that are
"local" to a translation unit. They must have external linkage, and the
unnamed namespace is the only way to provide that WITHOUT making them
accessible outside the translation unit, since they cannot be static.
Sep 7 '08 #4
On Sep 7, 3:28 am, blargg....@gishpuppy.com (blargg) wrote:
In article
<0c975cd6-22fb-4824-a4c7-4d5b58e49...@j22g2000hsf.googlegroups.com>,
Taras_96 <taras...@gmail.comwrote:
AFAIK external linkage allows you to refer to
variables/functions outside of the current translation unit.
A variable in an unnamed namespace is similar to declaring a
static variable, but according to the standard there is a
difference:
"While this is essentially true in practical effect, there
are subtle differences. Using static as shown here causes
"i" to have internal linkage. When declared in an unnamed
namespace without the use of static, it has external
linkage. This use of static is officially deprecated (C++
Standard 7.3.1.1/2)."
To me this means that the variable is accessible outside of
the translation unit. [...]
External linkage has other useful consequences as well. The
first that comes to mind is that the unnamed namespace allows
templates that are "local" to a translation unit. They must
have external linkage, and the unnamed namespace is the only
way to provide that WITHOUT making them accessible outside the
translation unit, since they cannot be static.
Not just templates, everything but references, variables and
functions. It's the only way to define a local, helper class
without risk of name conflict.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 7 '08 #5
On Sep 6, 8:53*pm, James Kanze <james.ka...@gmail.comwrote:
On Sep 6, 8:56 pm, Taras_96 <taras...@gmail.comwrote:
AFAIK external linkage allows you to refer to
variables/functions outside of the current translation unit. A
variable in an unnamed namespace is similar to declaring a
static variable, but according to the standard there is a
difference:
"While this is essentially true in practical effect, there are
subtle differences. *Using static as shown here causes "i" to
have internal linkage. *When declared in an unnamed namespace
without the use of static, it has external linkage. *This use
of static is officially deprecated (C++ Standard 7.3.1.1/2)."
To me this means that the variable is accessible outside of
the translation unit. However, Herb Schildt's book shows the
following:
------------------------------------------------------------------------------------------
While the use of static global declarations is still allowed
in C++, a better way to accomplish the same effect is to use
an unnamed namespace. For example:
File One
namespace {
int k;}
void f1() {
k = 99; // OK
}
File Two
extern int k;
void f2() {
k = 10; // error}
Here, k is also restricted to File One. The use of the unnamed
namespace rather than static is recommended for new code.
------------------------------------------------------------------------------------------
So how is it that 'k' has external linkage?

It has external linkage, just like any other variable. *In file
one, the definition is in a namespace with a name unique to the
file; in file 2, k is in global namespace. *This is more or less
Sorry, I don't think I made myself clear enough :*). I meant 'k' in
file 1 (ie: how is it that the 'k' in file 1 has external linkage?).
the same as if you had:

File One:
* * namespace TopSecrectName {
* * int k ;
* * }
* * using TopSecrectName ;
* * // *...

File Two
* * extern int k ;
* * // *...

Since the two k aren't in the same namespace, their qualified
names are different, and they can only be different entities.
This I understand :). I might be getting confused over the meaning of
'external linkage'. To me the defining characteristic is that during
the linking stage, the linker can 'link in' that variable.

So you could have:

file 1:
int h = 1;

file 2;
extern int h; // <- this refers to the k defined in file 1

[Side note.. does the 'k' variable in the 'TopSecretName' namespace
have internal linkage only?]

So, if in fact my interpretation of 'external linkage' is correct, and
(in my original example) the 'k' variable in the anonymous namespace
does have external linkage, then how can we get file 2 to refer to the
k variable in file 1?

Thanks

Taras
Sep 9 '08 #6
On Sep 6, 8:18*pm, "Victor Bazarov" <v.Abaza...@comAcast.netwrote:
Taras_96 wrote:
AFAIK external linkage allows you to refer to variables/functions
......
There is no way for the compiler to figure out the right name for the
variable when compiler *another* translation unit. *That's the trick
to make it "not available". *The name is made up unique while the
compiler is compiling that particular translation unit.
I don't quite understand.. perhaps there's a typo?
>
However, Herb Schildt's book shows the following:

Ugh! *Yuck! *I'm telling Mom! *...Mom, Taras said the "S" name, and
he is reading THAT book!...
:) - point taken. Does it help that I'm reading it in conjunction with
Bjarne Stroustrup's book?
>
Throw that book away, Taras, and get yourself a *real* C++ book.
Visitwww.accu.org, the book review section, to see what are the
recommended titles.
Sep 9 '08 #7
On Sep 9, 10:44 am, Taras_96 <taras...@gmail.comwrote:
On Sep 6, 8:53 pm, James Kanze <james.ka...@gmail.comwrote:
the same as if you had:
File One:
namespace TopSecrectName {
int k ;
}
using TopSecrectName ;
// ...
File Two
extern int k ;
// ...
Since the two k aren't in the same namespace, their qualified
names are different, and they can only be different entities.
This I understand :). I might be getting confused over the
meaning of 'external linkage'. To me the defining
characteristic is that during the linking stage, the linker
can 'link in' that variable.
That's sort of it. Formally, it means that the fully qualified
name refers to the same entity in different translation units.
In this case, any reference to ::TopSecrectName::k in any
translation unit would refer to the same entity, the variable k
defined in File One. As a programmer, of course, there's no
possible way you could refer to ::TopSecrectName::k, because
there's no way you can know what TopSecrectName really is. For
the compiler, this isn't necessarily true; the compiler can
"leak" the TopSecrectName somehow, and may actually do so in
some strategies of template instantiation (particularly if
export is involved). But that's an implementation detail you're
not supposed to see:-).
So you could have:
file 1:
int h = 1;
file 2;
extern int h; // <- this refers to the k defined in file 1
[Side note.. does the 'k' variable in the 'TopSecretName'
namespace have internal linkage only?]
No. It's just like any other variable. The only thing is that
the compiler generates a special name for the namespace, unique
to the translation unit.
So, if in fact my interpretation of 'external linkage' is
correct, and (in my original example) the 'k' variable in the
anonymous namespace does have external linkage, then how can
we get file 2 to refer to the k variable in file 1?
You can't, because you can't name the namespace its in.

In practice, you might be able to by looking at the mangled
generated name, demangling it to determine what the
TopSecretName actually was, and declaring a namespace with that
name. However, the compiler might use characters in that name
that you're not allowed to use in a name in C++ (g++ uses a . in
the name, for example), and its very likely that the compiler
generates a different name each time it recompiles the source
(true with both Sun CC and g++).

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 9 '08 #8
On Sep 9, 10:40*am, James Kanze <james.ka...@gmail.comwrote:
On Sep 9, 10:44 am, Taras_96 <taras...@gmail.comwrote:
No. *It's just like any other variable. *The only thing is that
the compiler generates a special name for the namespace, unique
to the translation unit.
So, if in fact my interpretation of 'external linkage' is
correct, and (in my original example) the 'k' variable in the
anonymous namespace does have external linkage, then how can
we get file 2 to refer to the k variable in file 1?

You can't, because you can't name the namespace its in.

In practice, you might be able to by looking at the mangled
generated name, demangling it to determine what the
TopSecretName actually was, and declaring a namespace with that
name. *However, the compiler might use characters in that name
that you're not allowed to use in a name in C++ (g++ uses a . in
the name, for example), and its very likely that the compiler
generates a different name each time it recompiles the source
(true with both Sun CC and g++).
I think I understand now.

In rough terms, the compiler generates a name for each namespace that
the linker can then use to link up matching namespaces. In the
anonymous namespace case, the compiler still generates that name (and
thus it has external linkage), but because that name is not visible to
the user (and the generation of that name is implementation specific),
then in practice you can't really refer to the anonyous namespace. If
you had the access to the generated name and the algorithm that
generates it, you could do something like this (in pseudo-code terms):

using inverse_generate_name(generated_anonymous_name_fro m file 1)

Sound about right ;)?

Taras
Sep 17 '08 #9
On Sep 9, 10:40*am, James Kanze <james.ka...@gmail.comwrote:
On Sep 9, 10:44 am, Taras_96 <taras...@gmail.comwrote:
No. *It's just like any other variable. *The only thing is that
the compiler generates a special name for the namespace, unique
to the translation unit.
So, if in fact my interpretation of 'external linkage' is
correct, and (in my original example) the 'k' variable in the
anonymous namespace does have external linkage, then how can
we get file 2 to refer to the k variable in file 1?

You can't, because you can't name the namespace its in.

In practice, you might be able to by looking at the mangled
generated name, demangling it to determine what the
TopSecretName actually was, and declaring a namespace with that
name. *However, the compiler might use characters in that name
that you're not allowed to use in a name in C++ (g++ uses a . in
the name, for example), and its very likely that the compiler
generates a different name each time it recompiles the source
(true with both Sun CC and g++).
I think I understand now.

In rough terms, the compiler generates a name for each namespace that
the linker can then use to link up matching namespaces. In the
anonymous namespace case, the compiler still generates that name (and
thus it has external linkage), but because that name is not visible to
the user (and the generation of that name is implementation specific),
then in practice you can't really refer to the anonyous namespace. If
you had the access to the generated name and the algorithm that
generates it, you could do something like this (in pseudo-code terms):

using inverse_generate_name(generated_anonymous_name_fro m file 1)

Sound about right ;)?

Taras
Sep 17 '08 #10
On Sep 17, 2:12 pm, Taras_96 <taras...@gmail.comwrote:
On Sep 9, 10:40 am, James Kanze <james.ka...@gmail.comwrote:
On Sep 9, 10:44 am, Taras_96 <taras...@gmail.comwrote:
No. It's just like any other variable. The only thing is that
the compiler generates a special name for the namespace, unique
to the translation unit.
So, if in fact my interpretation of 'external linkage' is
correct, and (in my original example) the 'k' variable in the
anonymous namespace does have external linkage, then how can
we get file 2 to refer to the k variable in file 1?
You can't, because you can't name the namespace its in.
In practice, you might be able to by looking at the mangled
generated name, demangling it to determine what the
TopSecretName actually was, and declaring a namespace with that
name. However, the compiler might use characters in that name
that you're not allowed to use in a name in C++ (g++ uses a . in
the name, for example), and its very likely that the compiler
generates a different name each time it recompiles the source
(true with both Sun CC and g++).
I think I understand now.
In rough terms, the compiler generates a name for each
namespace that the linker can then use to link up matching
namespaces. In the anonymous namespace case, the compiler
still generates that name (and thus it has external linkage),
but because that name is not visible to the user (and the
generation of that name is implementation specific), then in
practice you can't really refer to the anonyous namespace. If
you had the access to the generated name and the algorithm
that generates it, you could do something like this (in
pseudo-code terms):
using inverse_generate_name(generated_anonymous_name_fro m file 1)
Sound about right ;)?
It's exactly right. With the added aspect that most linkers
support more different characters in names that does C or C++,
so the compiler could insert characters which you couldn't even
use in a C++ name.

If you're curious about it, take a look at the mangled names the
compiler generates: compile something like:

namespace {
void function() {}
}

namespace KnownName {
void function() {}
}

and use nm (or the equivalent under Windows) to look at the
generated object file. (If you use a fairly long name for the
function, as I did above, you can pipe the output through grep,
and only see the relevant declarations.) Try recompiling: with
the two compilers I have handy (g++ and Sun CC), the name will
be different each time (and with g++, will contain a ., which
means that you cannot name it, even if you knew it).

The format of nm's output is implementation defined, but it
should also indicate that the symbols for both functions are
global.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
Sep 17 '08 #11
On Sep 17, 4:17*pm, James Kanze <james.ka...@gmail.comwrote:
On Sep 17, 2:12 pm, Taras_96 <taras...@gmail.comwrote:
On Sep 9, 10:40 am, James Kanze <james.ka...@gmail.comwrote:
On Sep 9, 10:44 am, Taras_96 <taras...@gmail.comwrote:
No. *It's just like any other variable. *The only thing is that
the compiler generates a special name for the namespace, unique
to the translation unit.
So, if in fact my interpretation of 'external linkage' is
correct, and (in my original example) the 'k' variable in the
anonymous namespace does have external linkage, then how can
we get file 2 to refer to the k variable in file 1?
You can't, because you can't name the namespace its in.
In practice, you might be able to by looking at the mangled
generated name, demangling it to determine what the
TopSecretName actually was, and declaring a namespace with that
name. *However, the compiler might use characters in that name
that you're not allowed to use in a name in C++ (g++ uses a . in
the name, for example), and its very likely that the compiler
generates a different name each time it recompiles the source
(true with both Sun CC and g++).
I think I understand now.
In rough terms, the compiler generates a name for each
namespace that the linker can then use to link up matching
namespaces. In the anonymous namespace case, the compiler
still generates that name (and thus it has external linkage),
but because that name is not visible to the user (and the
generation of that name is implementation specific), then in
practice you can't really refer to the anonyous namespace. If
you had the access to the generated name and the algorithm
that generates it, you could do something like this (in
pseudo-code terms):
using inverse_generate_name(generated_anonymous_name_fro m file 1)
Sound about right ;)?

It's exactly right. *With the added aspect that most linkers
support more different characters in names that does C or C++,
so the compiler could insert characters which you couldn't even
use in a C++ name.

If you're curious about it, take a look at the mangled names the
compiler generates: compile something like:

* * namespace {
* * void function() {}
* * }

* * namespace KnownName {
* * void function() {}
* * }

and use nm (or the equivalent under Windows) to look at the
generated object file. *(If you use a fairly long name for the
function, as I did above, you can pipe the output through grep,
and only see the relevant declarations.) *Try recompiling: with
the two compilers I have handy (g++ and Sun CC), the name will
be different each time (and with g++, will contain a ., which
means that you cannot name it, even if you knew it).

The format of nm's output is implementation defined, but it
should also indicate that the symbols for both functions are
global.
With a recent g++ the function in the anoymous namespace is optimized
away already at -O1, and nm doesn't show it. Even if the function has
extern linkage from the point of view of the standard, gcc treats it
as internal linkage for optimization purposes (for example it is free
to change calling conventions, as long as no pointers to it does
escape the translation unit), so even if one could figure out the
mangled name of the function, there is no way to refer to it from
another translation unit.

--
gpd
Sep 17 '08 #12
Thanks James :)
Sep 26 '08 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

4
by: Tron Thomas | last post by:
I have read that anonymous namespaces are preferred in C++ over declaring global statics because the namespace can hide information from other translation units and at the same time provide...
4
by: Dan Elliott | last post by:
Hello, Converting from a working C program to C++, I run into the following error: I have a header: (header.h) namespace shared{ ... struct X{ ...
12
by: bgeneto | last post by:
I know that it's a very basic question, but I can't figure out or find an answer to why do we have to specify a namespace, like this #include<string> using namespace std; when using the...
3
by: Frederick Gotham | last post by:
Back in the day, if you wanted a function to be self-contained within a translation unit, you defined the function as "static". If there were an external linkage function by the same name...
9
by: vthomasset | last post by:
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...
3
by: CrazyJohn | last post by:
Hi guys, This is my first time posting question here, if I break any rules, please kindly point out. And I'm really glad to be a part of this community. Here is my question, Our lecturer...
5
by: gauravbjain | last post by:
I am planning to move from ‘static’ keyword to anonymous namespace for variables/functions which are local to a translation unit. This is to move code closer to C++, since static for file level...
22
by: Luna Moon | last post by:
I am reading the book "C++ Annotations", and here is a quote from the book: Namespaces can be defined without a name. Such a namespace is anonymous and it restricts the visibility of the...
3
by: Al Grant | last post by:
Consider two translation units, (1): namespace { struct S { }; } struct D: S { virtual int f(void); }; and (2): #include <typeinfo> struct D; char const *f(D *p) { return...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.