Why Does Const Imply Internal Linkage in C++, When It Doesn't in C

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 or constexpr and neither explicitly declared extern 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 #included 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



Leave a reply



Submit