I understand that a static namespace function may be declared static, and the static keyword omitted from the definition of the function. What I have is the opposite, e.g.:
// in foo.h
namespace Foo
{
void bar();
}
// in foo.cpp
static void Foo::bar()
{
}
Does the static keyword have any effect here, or is it simply ignored? It compiles either way, and the functions are available to other translation units.
The given program is ill-formed as can be seen from dcl.stc which states:
The linkages implied by successive declarations for a given entity shall agree. That is, within a given scope, each declaration declaring the same variable name or the same overloading of a function name shall imply the same linkage.
(end quote)
Now, lets apply this to your example.
// in foo.h
namespace Foo
{
void bar(); //#1 external linkage
}
// in foo.cpp
static void Foo::bar() //#2 tries to give Foo::bar internal linkage
{
}
In the above code, the first declaration #1 of bar gives it external linkage while when implementing it in the source file(foo.cpp) in #2, you're trying to give it internal linkage. And so according to the above quoted statement, the given example is not valid.
Related
[basic.link]/6 (my emphasiss):
The name of a function declared in block scope and the name of a variable declared by a block scope extern declaration have linkage.
...
static void f();
static int i = 0;
void g() {
extern void f(); // internal linkage
int i; // #2 i has no linkage
{
extern void f(); // internal linkage <--
extern int i; // #3 external linkage
}
}
[basic.link]/7:
...
namespace X {
void p() {
q(); // error: q not yet declared
extern void q(); // q is a member of namespace X <--
}
void middle() {
q(); // error: q not yet declared
}
void q() { /* ... */ } // definition of X::q
}
void q() { /* ... */ } // some other, unrelated q
The externspecifiers pointed by the arrows are not necessary, given the very first sentence in paragraph [basic.link]/6 highlighted in bold characters above.Or am I missing something?
The externs are there to emphasize the respective comments, pointing out that the extern has no effect in certain circumstances (due to the rules outlined in that paragraph).
In the first example, f has internal linkage despite being declared extern, because it was first declared static at namespace-scope.
In the second exmaple, extern has no effect on the declaration because q is also declared at namespace scope without it (and X::q takes precedence over ::q).
I think the examples stave off some plausible but wrong ideas one might otherwise come up with.
In paragraph 6 one might expect f() to have external linkage since that is what extern "normally" (i.e. at file scope) means, but it's actually internal linkage because of the static declaration further up.
In paragraph 7 someone might expect extern void q(); to make q() available outside of (or in loose speech external to) p(), so it could be called in middle(), but that doesn't happen either.
Both would still be true without the extern keyword, but then it wouldn't be surprising to people expecting extern to mean something different.
I understand the use of unnamed namespaces to make functions and variables have internal linkage. Unnamed namespaces are not used in header files; only source files. Types declared in a source file cannot be used outside. So what's the use of putting types in unnamed namespaces?
See these links where it's mentioned that types can be put in unnamed namespaces:
Superiority of unnamed namespace over static?
Unnamed/anonymous namespaces vs. static functions
Why an unnamed namespace is a "superior" alternative to static?
Where do you want to put local types other than the unnamed namespace? Types can't have a linkage specifier like static. If they are not publicly known, e.g., because they are declared in a header, there is a fair chance that names of local types conflict, e.g., when two translation units define types with the same name. In that case you'd end up with an ODR violation. Defining the types inside an unnamed namespace eliminates this possibility.
To be a bit more concrete. Consider you have
// file demo.h
int foo();
double bar();
// file foo.cpp
struct helper { int i; };
int foo() { helper h{}; return h.i; }
// file bar.cpp
struct helper { double d; }
double bar() { helper h{}; return h.d; }
// file main.cpp
#include "demo.h"
int main() {
return foo() + bar();
}
If you link these three translation units, you have mismatching definitions of helper from foo.cpp and bar.cpp. The compiler/linker is not required to detect these but each type which is used in the program needs to have a consistent definition. Violating this constraints is known as violation of the "one definition rule" (ODR). Any violation of the ODR rule results in undefined behavior.
Given the comment it seems a bit more convincing is needed. The relevant section of the standard is 3.2 [basic.def.odr] paragraph 6:
There can be more than one definition of a class type (Clause 9), enumeration type (7.2), inline function with external linkage (7.1.2), class template (Clause 14), non-static function template (14.5.6), static data member
of a class template (14.5.1.3), member function of a class template (14.5.1.1), or template specialization for which some template parameters are not specified (14.7, 14.5.5) 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 each definition of D shall consist of the same sequence of tokens; and
[...]
There are plenty of further constraints but "shall consist of the same sequence of tokens" is clearly sufficient to rule out e.g. the definitions in the demo above from being legal.
So what's the use of putting types in unnamed namespaces?
You can create short, meaningful classes with names that maybe used in more than one file without the problem of name conflicts.
For example, I use two classes often in unnamed namespaces - Initializer and Helper.
namespace
{
struct Initializer
{
Initializer()
{
// Take care of things that need to be initialized at static
// initialization time.
}
};
struct Helper
{
// Provide functions that are useful for the implementation
// but not exposed to the users of the main interface.
};
// Take care of things that need to be initialized at static
// initialization time.
Initializer initializer;
}
I can repeat this pattern of code in as many files as I want without the names Initializer and Helper getting in the way.
Update, in response to comment by OP
file-1.cpp:
struct Initializer
{
Initializer();
};
Initializer::Initializer()
{
}
int main()
{
Initializer init;
}
file-2.cpp:
struct Initializer
{
Initializer();
};
Initializer::Initializer()
{
}
Command to build:
g++ file-1.cpp file-2.cpp
I get linker error message about multiple definitions of Initializer::Initializer(). Please note that the standard does not require the linker to produce this error. From section 3.2/4:
Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required.
The linker does not produce an error if the functions are defined inline:
struct Initializer
{
Initializer() {}
};
That's OK for a simple case like this since the implementations are identical. If the inline implementations are different, the program is subject to undefined behavior.
I might be a bit late for answering the question the OP made but since I think the answer is not fully clear, I would like to help future readers.
Lets try a test... compile the following files:
//main.cpp
#include <iostream>
#include "test.hpp"
class Test {
public:
void talk() {
std::cout<<"I'm test MAIN\n";
}
};
int main()
{
Test t;
t.talk();
testfunc();
}
//test.hpp
void testfunc();
//test.cpp
#include <iostream>
class Test {
public:
void talk()
{
std::cout<<"I'm test 2\n";
}
};
void testfunc() {
Test t;
t.talk();
}
Now run the executable.
You would expect to see:
I'm test MAIN
I'm test 2
What you should see thought is:
I'm test MAIN
I'm test MAIN
What happened?!?!!
Now try putting an unnamed namespace around the "Test" class in "test.cpp" like so:
#include <iostream>
#include "test.hpp"
namespace{
class Test {
public:
void talk()
{
std::cout<<"I'm test 2\n";
}
};
}
void testfunc() {
Test t;
t.talk();
}
Compile it again and run.
The output should be:
I'm test MAIN
I'm test 2
Wow! It works!
As it turns out, it is important to define classes inside unnamed namespaces so that you get the proper functionality out of them when two class names in different translation units are identical.
Now as to why that is the case, I haven't done any research on it (maybe someone could help here?) and so I can't really tell you for sure. I'm answering purely from a practical standpoint.
What I would suspect though is that, while it is true that C structs are indeed local to a translation unit, they are a bit different from classes since classes in c++ usually have behavior assigned to them. Behavior means functions and as we know, functions are not local to the translation unit.
This is just my assumption.
I'm asking this question as a follow up from this post. They say that the extern block declaration has external linkage and not internal linkage, but I'm not sure why:
static int i = 0; // #1
void g() {
extern int i; // #3 external linkage
}
Why doesn't the extern declaration take the linkage of i (internal linkage)? The quote in the post seems to allow that. In the example after the OP's quote it has:
static void f();
void g() {
extern void f(); // internal linkage
// ...
}
and it says that the extern declaration has internal linkage. Why is there a difference when using variables and functions?
Because variable "i" has static storage. So, in terms of your snippet,
omitting the "static" statement will produce "no linkage"
applying "static" statement will produce "external linkage" (as static storage is quite special part of the C/C++ runtime infrastructure).
Also, you may find this discussion interesting:
Understanding static storage class in C
What is the C++ equvalent for translation unit local static function in C?
For example having the following in bar.c:
static void bar() {
// ...
}
In C++, would this be written as a a private member function like
class foo {
void bar();
};
void foo::bar() {
// ...
}
A private member function implicitly introduces the this pointer as parameter, so it's not really comparable to the C style static function. But even a private static member function bar() would be seen in the public interface (and staying accessible for the linker), and isn't comparable as well.
While accessible scope of those functions seems to be similar, these options don't look like good replacements for the mentioned C style static function syntax.
Is the equivalent a function in an unnamed namespace, that's visible to the current translation unit only?
namespace {
void bar() {
// ...
}
}
[C] Static function with file scope.
static void bar() { ... }
This will create a function named bar that has internal linkage.
[C++] Static function with file scope
static void bar() { ... }
This will create a function named bar that has internal linkage.
[C++] Unnamed namespace
namespace {
void bar() { ... }
}
This will create a function named bar that has internal linkage.
Conclusions
They are all identical. I'd probably recommend using the unnamed namespace in C++, because it gets rid of some of the overloading of the static keyword. But from the perspective of what your code does, it doesn't matter.
Sidebar: What does internal linkage mean?
In C and C++, we have three kinds of linkage: External, Internal and No linkage. To define these, I'm going to quote from C++ 2011 Section 3.5 Paragraph 2:
A name is said to have linkage when it might denote the same object, reference, function, type, template, namespace or value as a name introduced by a declaration in another scope:
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.
C 2011 has similar language at Section 6.2.2 Paragraph 2:
In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function. Each declaration of an identifier with no linkage denotes a unique entity.
So names that have internal linkage are only visible in the translation unit that they were found in.
Sidebar: Let's include an example of how internal linkage works in practice:
Let's create 2 c++ files. bar.cc will contain just a function with internal linkage:
static void bar() {}
We'll also create main.cc, which will try to use that bar().
extern void bar();
int main() {
bar();
}
If we compile this, our linker will complain. there is no function named bar that we can find from the main.cc translation unit. This is the expected behavior of internal linkage.
Undefined symbols for architecture x86_64:
"bar()", referenced from:
_main in main-c16bef.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I have a class that had an inline member, but I later decided that I wanted to remove the implementation from the headers so I moved the members body of the functions out to a cpp file. At first I just left the inlined signature in the header file (sloppy me) and the program failed to link correctly. Then I fixed my header and it all works fine, of course.
But wasn't inline totally optional?
In code:
First:
//Class.h
class MyClass
{
void inline foo()
{}
};
Next changed to (won't link):
//Class.h
class MyClass
{
void inline foo();
};
//Class.cpp
void MyClass::foo()
{}
And then to (will work fine):
//Class.h
class MyClass
{
void foo();
};
//Class.cpp
void MyClass::foo()
{}
I thought inline was optional, and imagined I might get by with a warning for my sloppiness, but didn't expect a linking error. What's the correct/standard thing a compiler should do in this case, did I deserve my error according to the standard?
Indeed, there is this one definition rule saying that an inline function must be defined in every translation unit it is used. Gory details follow. First 3.2/3:
Every program shall contain exactly one definition of every non-inline function or object that is used in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8).
An inline function shall be defined in every translation unit in which it is used.
And of course 7.1.2/4:
An inline function shall be defined in every translation unit in which it is used and shall have exactly the same definition in every case (3.2). [Note: a call to the inline function may be encountered before its definition appears in the translation unit. ] If a function with external linkage is declared inline in one translation unit, it shall be declared inline in all translation units in which it appears; no diagnostic is required. An inline function with external linkage shall have the same address in all translation units. A static local variable in an extern inline function always refers to the same object. A string literal in an extern inline function is the same object in different translation units.
However, if you define your function within the class definition, it is implicitly declared as inline function. That will allow you to include the class definition containing that inline function body multiple times in your program. Since the function has external linkage, any definition of it will refer to the same function (or more gory - to the same entity).
Gory details about my claim. First 3.5/5:
In addition, a member function, static data member, class or enumeration of class scope has external linkage if the name of the class has external linkage.
Then 3.5/4:
A name having namespace scope has external linkage if it is the name of [...] a named class (clause 9), or an unnamed class defined in a typedef declaration in which the class has the typedef name for linkage purposes.
This "name for linkage purposes" is this fun thing:
typedef struct { [...] } the_name;
Since now you have multiple definitions of the same entity in your programs, another thing of the ODR happens to restrict you. 3.2/5 follows with boring stuff.
There can be more than one definition of a class type (clause 9), enumeration type (7.2), inline function with external linkage (7.1.2) [...] 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
each definition of D shall consist of the same sequence of tokens; and
in each definition of D, corresponding names, looked up according to 3.4, shall refer to an entity defined within the definition of D, or shall refer to the same entity, after overload resolution (13.3) and after matching of partial template specialization (14.8.3) [...]
I cut off some unimportant stuff now. The above are the two important one to remember about inline functions. If you define an extern inline function multiple times, but do define it differently, or if you define it and names used within it resolve to different entities, then you are doing undefined behavior.
The rule that the function has to be defined in every TU in which it is used is easy to remember. And that it is the same is also easy to remember. But what about that name resolution thingy? Here some example. Consider a static function assert_it:
static void assert_it() { [...] }
Now, since static will give it internal linkage, when you include it into multiple translation units, then each definition will define a different entity. This means that you are not allowed to use assert_it from an extern inline function that's going to be defined multiple times in the program: Because what happens is that the inline function will refer to one entity called assert_it in one TU, but to another entity of the same name in another TU. You will find that this all is boring theory and compilers won't probably complain, but i found this example in particular shows the relation between the ODR and entities.
What follows is getting back to your particular problem again.
Following are the same things:
struct A { void f() { } };
struct A { inline void f(); }; void A::f() { } // same TU!
But this one is different, since the function is non-inline. You will violate the ODR, since you have more than one definition of f if you include the header more than once
struct A { void f(); }; void A::f() { } // evil!
Now if you put inline on the declaration of f inside the class, but then omit defining it in the header, then you violate 3.2/3 (and 7.1.2/4 which says the same thing, just more elaborating), since the function isn't defined in that translation unit!
Note that in C (C99), inline has different semantics than in C++. If you create an extern inline function, you should first read some good paper (preferably the Standard), since those are really tricky in C (basically, any used inline-definition of a function will need another, non-inline function definition in another TU. static inline functions in C are easy to handle. They behave like any other function, apart of having the usual "inline substitution" hint. static inline in both C and C++ serve only as a inline-substitution hint. Since static will already create a different entity any time it's used (because of internal linkage), inline will just add the inline-substitution hint - not more.
Whether or not the method is actually inlined is at the sole discretion of the compiler. However the presence of the inline keyword will also affect the linkage of the method.
C++ linkage is not my specialty so I'll defer to the links for a better explanation.
http://publib.boulder.ibm.com/infocenter/zos/v1r9/index.jsp?topic=/com.ibm.zos.r9.cbclx01/inline_linkage.htm
http://en.wikipedia.org/wiki/Inline_function
Alternately you can just wait for litb to provide the gory details in an hour or so ;)
Point to note: when method is declared inline, its definition MUST be together with its declaration.
Regarding harshath.jr's answer, a method need not be declared inline if its definition has the "inline" keyword, and that definition is available in the same header, i.e.:
class foo
{
void bar();
};
inline void foo::bar()
{
...
}
This is useful for conditionally inlining a method depending on whether or not the build is "debug" or "release" like so:
// Header - foo.h
class foo
{
void bar(); // Conditionally inlined.
};
#ifndef FOO_DEBUG
# include "foo.inl"
#endif
The "inline" file could look like:
// Inline Functions/Methods - foo.inl
#ifndef FOO_DEBUG
# define FOO_INLINE inline
#else
# define FOO_INLINE
#endif
FOO_INLINE void foo::bar()
{
...
}
and the implementation could like the following:
// Implementation file - foo.cpp
#ifdef FOO_DEBUG
# include "foo.inl"
#endif
...
It's not exactly pretty but it has it's uses when aggressive inline becomes a debugging headache.