Why does const imply internal linkage in C++, when it doesn't in C?
I believe you mean
Why does const imply internal linkage in C++
It's true that if you declare a const object at namespace scope, then it has internal linkage.
Appendix C (C++11, C.1.2) gives the rationale
Change: A name of file scope that is explicitly declared const, and not explicitly declared extern, has internal linkage, while in C it would have external linkage
Rationale: Because const objects can be used as compile-time values in C++, this feature urges programmers to provide explicit initializer values for each const. This feature allows the user to put const objects in header files that are included in many compilation units.
Does const reference have external linkage in C++?
The reference itself isn't const
, just the object it refers to; so (arguably) this rule doesn't give the reference internal linkage.
It doesn't make sense for a reference to be declared const
. The C++11 standard clarifies the wording:
a variable that is explicitly declared
const
orconstexpr
and neither explicitly declaredextern
nor previously declared to have external linkage
with no mention of the nonsensical concept of references declared const
.
Linkage of various const/static variables
const double pi1 = 3.14; // (e)
extern const double pi1; // (f) valid and 'pi1' is internal
My interpretation is as follows. When considering the linkage of a name we consider previous declarations as well as the one being interpreted at this point in the parse. This is why static int a; extern int a;
is OK, but extern int b; static int b;
is not.
On encountering the first declaration we note that pi1
is explicitly declared const
but neither explicitly declared extern
nor previously declared to have external linkage. This matches one of the options of 3.5/2 therefore pi1
has internal linkage.
On encountering the second declaration we ask is pi1
the name of an object that is explicitly declared const
but neither explicitly declared extern
nor [... blah ...]. I contend that it is because it was so declared at point (e). Sure, it isn't declared that way everywhere but in the same way a
was the name of an object declared static
when we were considering the extern int a;
declaration even though it wasn't declared static
everywhere. This, to me, means that the declaration (f) doesn't imply a different linkage from declaration (e).
Why multiple definition error in C++ not caused by const int declaration?
The #define
for USB_MANAGER_DBUS_OBJ_PATH
is constant across compilation units, it is a text substitution.
So is the const int
for DBUS_CONNECTION_MAX_RETRY_TIME
constant across TU. The const
makes the variable read only, it's essentially not declaring it as a modifiable lvalue, it has an implicit internal linkage, from these posts.
const char* USB_MANAGER_DBUS_SERVICE = "com.USBService";
Why does USB_MANAGER_DBUS_SERVICE
cause a linker error?
It is not const
, as in the pointer is not a constant value, only what is being pointed to.
const char* const USB_MANAGER_DBUS_SERVICE = "com.USBService";
// ^^^^^ added const
Would be const
.
What is external linkage and internal linkage?
When you write an implementation file (.cpp
, .cxx
, etc) your compiler generates a translation unit. This is the source file from your implementation plus all the headers you #include
d in it.
Internal linkage refers to everything only in scope of a translation unit.
External linkage refers to things that exist beyond a particular translation unit. In other words, accessible through the whole program, which is the combination of all translation units (or object files).
Extern and const in C++
When const float fallingTime = 0.5f;
is defined in a header, a translation unit may or may not store the value in the data section of your binary.
If no code in a translation unit takes an address or reference to fallingTime
there is no reason for the compiler to allocate the value in the data section at all. The compiler is likely to replace usage of fallingTime
with its value because its definition is available in every translation unit at compile time.
With extern const
the generated code will have to load the value of fallingTime
from memory because its definition is not available at compile time in any other translation unit but the one that defines the value of fallingTime
.
Related Topics
How to Call the Base Class Constructor
Is It Safe to Assume That Stl Vector Storage Is Always Contiguous
Using Local Classes With Stl Algorithms
Is Is_Constexpr Possible in C++11
How to Use Break to Exit Multiple Nested 'For' Loops
How to Sort a Vector of Pairs Based on the Second Element of the Pair
How to Get the Index of an Iterator of an Std::Vector
Std::Vector Versus Std::Array in C++
Best Way to Extract a Subvector from a Vector
What Is the Purpose of Std::Launder
Is Floating-Point Addition and Multiplication Associative
Is It a Conforming Compiler Extension to Treat Non-Constexpr Standard Library Functions as Constexpr
What Does It Mean to Have an Undefined Reference to a Static Member