I have 2 files A.cpp and B.cpp which look something like
A.cpp
----------
class w
{
public:
w();
};
B.cpp
-----------
class w
{
public:
w();
};
Now I read somewhere (http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/index.jsp?topic=%2Fcom.ibm.xlcpp8a.doc%2Flanguage%2Fref%2Fcplr082.htm) that classes have external linkage. So while building I was expecting a multiple definition error but on the contrary it worked like charm. However when I defined class w in A.cpp, I got the redefinition error which makes me believe that classes have internal linkage.
Am I missing something here?
The correct answer is yes, the name of a class may have external linkage. The previous answers are wrong and misleading. The code you show is legal and common.
The name of a class in C++03 can either have external linkage or no linkage. In C++11 the name of a class may additionally have internal linkage.
C++03
§3.5 [basic.link]
Class names can have external linkage.
Class names can have no linkage.
In C++11 the first quote changes and class names at namespace scope may now have external or internal linkage.
The second quote also changes but the conclusion is the same, class names may have no linkage.
Some of the answers here conflate the abstract notion of linkage in the C++ Standard with the computer program known as a linker. The C++ Standard does not give special meaning to the word symbol. A symbol is what a linker resolves when combining object files into an executable. Formally, this is irrelevant to the notion of linkage in the C++ Standard. The document only ever addresses linkers in a footnote regarding character encoding.
Finally, your example is legal C++ and is not an ODR violation. Consider the following.
Perhaps this looks familiar. After preprocessor directives are evaluated we are left with the original example. The Wikipedia link provided by Alok Save even states this as an exception.
The ODR rule takes content into consideration. What you show is in fact required in order for a translation unit to use a class as a complete type.
§3.5 [basic.def.odr]
edit - The second half of James Kanze's answer got this right.
Classes have no linkage to be pedantic.
Linkage only applies to
symbols
, that is, functions and variables, or code and data.Technically, as Maxim points out, linkage applies to symbols, not to the entities they denote. But the linkage of a symbol is partially determined by what it denotes: symbols which name classes defined at namespace scope have external linkage, and
w
denotes the same entity in bothA.cpp
andB.cpp
.C++ has two different sets of rules concerning the definition of entities: some entities, like functions or variables, may only be defined once in the entire program. Defining them more than once will result in undefined behavior; most implementations will (most of the time, anyway) give a multiple definition error, but this is not required or guaranteed. Other entities, such as classes or templates, are required to be defined in each translation unit which uses them, with the further requirement that every definition be identical: same sequence of tokens, and all symbols binding to the same entity, with a very limited exception for symbols in constant expressions, provided the address is never taken. Violating these requirements is also undefined behavior, but in this case, most systems will not even warn.
The class declaration
does not produce any code or symbols, so there is nothing that could be linked and have "linkage". However, when your constructor w() is defined ...
it will have external linkage. If you define it in both A.cpp and B.cpp, there will be a name collision; what happens then depends on your linker. MSVC linkers e.g. will terminate with an error LNK2005 "function already defined" and/or LNK1169 "one or more multiply defined symbols found". The GNU g++ linker will behave similar. (For duplicate template methods, they will instead eliminate all but one instance; GCC docs call this the "Borland model").
There are four ways to resolve this problem:
class w
, put them into different namespaces.Everying in an anonymous namespace has internal linkage, so you may also use it as a replacement for
static
declarations (which are not possible for class methods).No 4 will only work if your class has no static fields (class variables), and it will duplicate the code of the inline methods for each function call.
External linkage means the symbol (function or global variable) is accessible throughout your program and Internal linkage means that it's only accessible in one translation unit. you explicitly control the linkage of a symbol by using the extern and static keywords and the default linkage is extern for non-const symbols and static (internal) for const symbols.
A name with external linkage denotes an entity that can be referenced via names declared in the same scope or in other scopes of the same translation unit (just as with internal linkage), or additionally in other translation units.
The program actually violates the One Definition Rule but it is hard for the compiler to detect the error, because they are in different compilation units. And even the linker seems cannot detect it as an error.
C++ allows a workaround to bypass the One Definition Rule by making use of namespace.
[UPDATE] From C++03 Standard
§ 3.2 One definition rule, section 5 states:
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 each definition of D shall consist of the same sequence of tokens.