This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Unnamed/anonymous namespaces vs. static functions
Is this completely redundant, or may there be a reason to do this?
namespace {
static void f() {
...
}
}
It looks redundant to me -- either being declared static or being in an anonymous namespace means it has internal linkage.
§3.5/3:
A name having namespace scope (3.3.6) has internal linkage if it is the name of:
— a variable, function or function template that is explicitly declared static;
§3.5/4:
[...] An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. [...] A name having namespace scope that has not
been given internal linkage above has the same linkage as the enclosing namespace if it is the name of
— a variable; or
— a function; or
So, as it is right now, it has internal linkage because it's explicitly declared static. If it wasn't explicitly declared static, it would have internal linkage because it's declared inside an unnamed namespace. Same effect either way.
Note that here I'm replying specifically about a function -- there are a few obscure cases where there's a difference when you're dealing with the name of a type (e.g., class/struct/union), but I don't know of any such thing that applies in the case of a function.
As far as what internal linkage really means, that's one of those places the standard is actually quite direct and clear. It's probably best to quote the definitions of all three possibilities (§3.5/2):
When a name has external linkage, the entity it denotes can be referred to by names from scopes of other translation units or from other scopes of the same translation unit.
When a name has internal linkage, the entity it denotes can be referred to by names from other scopes in the same translation unit.
When a name has no linkage, the entity it denotes cannot be referred to by names from other scopes.
Note that the italics above match those in the standard, which is its way of saying that these sentences define what those phrases mean throughout the rest of the standard.
Related
Let's say I have 2 TUs with 2 non-inline function definitions with external linkage which differ only in their return types.
Which paragraph(s) my program violates?
[basic.def.odr]/4 says:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program outside of a discarded statement; no diagnostic required.
But
This paragraph says "that is odr-used" which may or may not be the case.
How do I tell if I define the same non-inline function in different TUs, after all? [over.dcl]/1 speaks about the same scope.
I believe you're looking for: [basic.link]/9:
Two names that are the same ([basic.pre]) and that are declared in different scopes shall denote the same variable, function, type, template or namespace if
both names have external or module linkage and are declared in declarations attached to the same module, or else both names have internal linkage and are declared in the same translation unit; and
both names refer to members of the same namespace or to members, not by inheritance, of the same class; and
when both names denote functions or function templates, the signatures ([defns.signature], [defns.signature.templ]) are the same.
If multiple declarations of the same name with external linkage would declare the same entity except that they are attached to different modules, the program is ill-formed; no diagnostic is required. [ Note: using-declarations, typedef declarations, and alias-declarations do not declare entities, but merely introduce synonyms. Similarly, using-directives do not declare entities. — end note ]
And [basic.link]/11:
After all adjustments of types (during which typedefs are replaced by their definitions), the types specified by all declarations referring to a given variable or function shall be identical, except that declarations for an array object can specify array types that differ by the presence or absence of a major array bound ([dcl.array]). A violation of this rule on type identity does not require a diagnostic.
And [defns.signature]:
⟨function⟩ name, parameter-type-list ([dcl.fct]), and enclosing namespace (if any)
The return type isn't part of the signature, so you're violating the rule that same signature means same entity.
Generally speaking, all discussions of scope and name lookup in the standard are pretty broken until Davis "The Hero We Don't Deserve" Herring's work goes through.
I think I understood that anonymous namespace can be used to make the symbols local to current translation unit. But what about structure definitions, can I assume that they do refer to the same type ?
MyClass.h:
namespace {
class MyClass {};
}
A.h:
#include "MyClass.h"
class A {
MyClass* impl;
void op();
}
A.cpp translation unit 1:
#include "A.h"
void A::op() {
// Let *this->impl refer to a type X.
}
B.cpp translation unit 2:
#include "A.h"
void global_op(const A& a) {
// Can I assume that *a->impl refer to same type X ?
}
No, they do not refer to the same type. The header MyClass.h contains a definition of a class type MyClass inside an unnamed namespace. An unnamed namespace basically makes everything inside it (yes, types too) have internal linkage [basic.link]/6. You have two translation units, each (indirectly) includes MyClass.h, each gets it's own unnamed namespace with it's own MyClass [basic.link]/11.
Think of an unnamed namespace as being a namespace that has a distinct name for each translation unit. So the MyClass in translation unit A is actually $somerandomstringA$::MyClass, while the MyClass in translation unit B is actually $somerandomstringB$::MyClass…
As discussed down in the comments to this answer, be aware of the fact that the program you described above will contain an ODR violation (specifically [basic.def.odr]/12.2) as a result of your class A being defined to contain a member of type MyClass*, which has a different meaning in different translation units.
This program has undefined behavior, since each translation unit defines class ::A but with two different meanings.
An anonymous namespace has internal linkage ([basic.link]/4). The type MyClass has the same linkage as its namespace, so also internal linkage ([basic.link]/4.3). And internal linkage means that the type can only be named from the same translation units, so the two translation units formed from A.cpp and B.cpp define two different types named MyClass. This isn't a problem, yet.
But the global namespace and class A have external linkage. There are two definitions of the single type ::A, but they give the member impl two different types. This is a One Definition Rule violation.
(Although we often say "the ODR", there are really essentially two flavors: [basic.def.odr]/10 applies to things like objects and functions which are namespace members and not marked inline, and says the program can only have one definition, in one TU; so we usually put those in source files. [basic.def.odr]/12 applies to things like types, things marked inline, and declarations with template parameters, and says multiple TUs may each have one definition, but all must have the same token spelling (after preprocessing) and the same meaning; so we often put those in header files so that multiple TUs can use a common definition.)
Specifically here, the program violates [basic.def.odr]/12.2:
There can be more than one definition of a class type, ... in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then
...; and
in each definition of D, corresponding names, looked up according to [basic.lookup], shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution and after matching of partial template specialization ([temp.over]), except that a name can refer to
a non-volatile const object with internal or no linkage if ..., or
a reference with internal or no linkage initialized with a constant expression such that ...;
and ....
... If the definitions of D do not satisfy these requirements, then the behavior is undefined.
Here MyClass is a name within the definitions of class ::A but referring to two different entities, and not falling into any of the specifically permitted categories.
This might work in practice for many systems, since both translation units will see the same member names, types, and offsets within their own MyClass types. But if MyClass ever ends up being used in "name mangling", that will go wrong. And anyway, it's safest to avoid undefined behavior whenever you can.
C(ISO/IEC 9899:2011) has no concept of namespace, when referring global variable's scope, the standard use file scope:
Every other identifier has scope determined by the placement of its declaration (in a declarator or type specifier). If the declarator or type specifier that declares the identifier appears outside of any block or list of parameters, the identifier has file scope, which terminates at the end of the translation unit. If the declarator or type specifier that declares the identifier appears inside a block or within the list of parameter declarations in a function definition, the identifier has block scope, which terminates at the end of the associated block. If the declarator or type specifier that declares the identifier appears within the list of parameter declarations in a function prototype (not part of a function definition), the identifier has function prototype scope, which terminates at the end of the function declarator. If an identifier designates two different entities in the same name space, the scopes might overlap. If so, the scope of one entity (the inner scope) will end strictly before the scope of the other entity (the outer scope). Within the inner scope, the identifier designates the entity declared in the inner scope; the entity declared in the outer scope is hidden (and not visible) within the inner scope.
However, in c++(at least ISO/IEC 14882:2011), file scope is never used and use namespace scope instead:
The declarative region of a namespace-definition is its namespace-body. Entities declared in a namespace-body are said to be members of the namespace, and names introduced by these declarations into the declarative region of the namespace are said to be member names of the namespace. A namespace member name has namespace scope. Its potential scope includes its namespace from the name's point of declaration onwards; and for each using-directive ([namespace.udir]) that nominates the member's namespace, the member's potential scope includes that portion of the potential scope of the using-directive that follows the member's point of declaration.
As we know, c++ is inspired a lot from C, so many definitions of terms also derive from c, though they are virtually two different languages now. IMO, there should be a reason that c++ use namespace scope instead of file scope, but I don't know. What's behind it?
The C++ standard doesn't mention file scope because it isn't trying to explain things in C terms. It defines and uses its own terms. In this case, it is under the definition of namespaces:
[basic.namespace]
2 The outermost declarative region of a translation unit is a
namespace; see [basic.scope.namespace].
This declarative region, in C++ terms, is the equivalent of C's file scope. The C++ standard uses these definitions because it intends to support namespace declarations, that allow us to partition this scope into smaller pieces.
C has no such feature, so it speaks only of things at file scope as the its outermost scope, because said definition is enough.
You're asking about file scope, not function scope.
The reason that C++ instead talks about namespace scope, is that it has namespaces. C doesn't. So of course C wouldn't have namespace scope.
C and C++ are different languages. C++ doesn't change things to "not be C", it changes things because its designers consider the changes to make the language inherently "better", either directly, or by consequence of the existence of some C++-only feature that in turn makes the language "better" than C.
clang, gcc and VS2013 all complain about redefinition of w in main(), but I couldn't find in the Standard anything disallowing this.
namespace N {
extern int j;
int j;
}
int main()
{
extern int w;
int w;
}
These paragraphs say something about the use of an extern declaration in block scope, but they don't seem to justify the error message:
§3.3.1/4
Given a set of declarations in a single declarative region, ...
[ Note: These restrictions apply to the declarative region into which
a name is introduced, which is not necessarily the same as the region
in which the declaration occurs. In particular,
elaborated-type-specifiers (7.1.6.3) and friend declarations (11.3)
may introduce a (possibly not visible) name into an enclosing
namespace; these restrictions apply to that region. Local extern
declarations (3.5) may introduce a name into the declarative region
where the declaration appears and also introduce a (possibly not
visible) name into an enclosing namespace; these restrictions apply to
both regions. —end note ]
§3.3.2/10
[ Note: Friend declarations refer to functions or classes that are
members of the nearest enclosing namespace, but they do not introduce
new names into that namespace (7.3.1.2). Function declarations at
block scope and variable declarations with the extern specifier at
block scope refer to declarations that are members of an enclosing
namespace, but they do not introduce new names into that scope. —end
note ]
I believe this is mostly covered by §3.5/6.
In particular:
The name of a function declared in block scope and the name of a variable declared by a block scope extern declaration have linkage. If there is a visible declaration of an entity with linkage having the same name and type, ignoring entities declared outside the innermost enclosing namespace scope, the block scope declaration declares that same entity and receives the linkage of the previous declaration. If there is more than one such matching entity, the program is ill-formed. Otherwise, if no matching entity is found, the block scope entity
receives external linkage.
So, the extern int w; declares a w that has linkage (external linkage, in this case, since no matching entity is visible at that point).
Then you attempt to define a local w which has no linkage (by §3.5/8).
That gives two declarations of the same name at the same scope, but with different linkages. That's prohibited by §3.3.1/4:
Given a set of declarations in a single declarative region, each of which specifies the same unqualified name,
they shall all refer to the same entity, or all refer to functions and function templates; or
exactly one declaration shall declare a class name or enumeration name that is not a typedef name
and the other declarations shall all refer to the same variable or enumerator, or all refer to functions and function templates; in this case the class name or enumeration name is hidden (3.3.10).
Neither refers to a function, function template, class name, or enumeration name, so none of these "escape clauses" applies. The two declarations must refer to the same entity, which must have both external linkage and no linkage. Since that's impossible, the code is ill-formed.
Here is my interpretation: In §3.3.1/3 the standard says:
The names declared by a declaration are introduced into the scope in which the declaration occurs, except that the presence of a friend specifier (11.3), certain uses of the elaborated-type-specifier (7.1.6.3), and using-directives (7.3.4) alter this general behavior.
As extern declarations are not listed as exception, the name is introduced in the block scope, which is why you get the error when you try to redeclare it.
The paragraph you quoted says
but they do not introduce new names into that scope.
which is a bit ambiguous, as both block scope and namespace scope are mentioned. The standard would contradict itself if it referred to block scope, so I assume that namespace scope is meant.
Why don't symbols (functions and variables) that are defined in an anonymous namespace have internal linkage as with static keyword? If a function is not visible/accessible outside, what is the reason to have external linkage?
In C++03, names with internal linkage were forbidden from being used as template arguments[*]. So, names of most things in unnamed namespaces had external linkage to allow their use with templates. You could explicitly give a name internal linkage in an unnamed namespace by declaring it static, same as in a named or global namespace.
Both things changed in C++11 -- names in unnamed namespaces have internal linkage by default (3.5/4), and names with internal linkage can be used as template arguments.
[*] for types, it must have external linkage. For objects and functions, it must have external linkage if its address is used as a template argument, although it's OK for example to use as a template argument the value of a const integer with internal linkage.