Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
166 views
in Technique[技术] by (71.8m points)

c++ - Do classes have external linkage?

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 (https://en.cppreference.com/w/cpp/language/static) 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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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]

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

Class names can have external linkage.

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 (7.1.3)

Class names can have no linkage.

Names not covered by these rules have no linkage. Moreover, except as noted, a name declared in a local scope (3.3.2) has no linkage. A name with no linkage (notably, the name of a class or enumeration declared in a local scope (3.3.2)) shall not be used to declare an entity with linkage.

In C++11 the first quote changes and class names at namespace scope may now have external or internal linkage.

An unnamed namespace or a namespace declared directly or indirectly within an unnamed namespace has internal linkage. All other namespaces have external linkage. A name having namespace scope that has not been given internal linkage above [class names were not] has the same linkage as the enclosing namespace 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 (7.1.3);

The second quote also changes but the conclusion is the same, class names may have no linkage.

Names not covered by these rules have no linkage. Moreover, except as noted, a name declared at block scope (3.3.3) has no linkage. A type is said to have linkage if and only if:

— it is a class or enumeration type that is named (or has a name for linkage purposes (7.1.3)) and the name has linkage; or

— it is an unnamed class or enumeration member of a class with 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.

C.h
----------
class w
{
public:
    w();
};


A.cpp
-----------
#include "C.h"


B.cpp
-----------
#include "C.h"

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.

Some things, like types, templates, and extern inline functions, can be defined in more than one translation unit. For a given entity, each definition must be the same.

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]

Exactly one definition of a class is required in a translation unit if the class is used in a way that requires the class type to be complete.

edit - The second half of James Kanze's answer got this right.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...