C++ semantics of `static const` vs `const`

C++

C++ Problem Overview


In C++ specifically, what are the semantic differences between for example:

static const int x = 0 ;

and

const int x = 0 ;

for both static as a linkage and a storage class specifier (i.e. inside and outside a function).

C++ Solutions


Solution 1 - C++

At file scope, no difference in C++. const makes internal linkage the default, and all global variables have static lifetime. But the first variant has the same behavior in C, so that may be a good reason to use it.

Within a function, the second version can be computed from parameters. In C or C++ it doesn't have to be a compile-time constant like some other languages require.

Within a class, basically the same thing as for functions. An instance const value can be computed in the ctor-initializer-list. A static const is set during startup initialization and remains unchanged for the rest of the program. (Note: the code for static members looks a little different because declaration and initialization are separated.)

Remember, in C++, const means read-only, not constant. If you have a pointer-to-const then other parts of the program may change the value while you're not looking. If the variable was defined with const, then no one can change it after initialization but initialization can still be arbitrarily complex.

Solution 2 - C++

C++17 standard draft on const implies static at file scope

This is the quote for what was mentioned at: https://stackoverflow.com/a/3709257/895245

C++17 n4659 standard draft 6.5 "Program and linkage":

> 3 A name having namespace scope (6.3.6) has internal linkage if it is the name of

> - (3.1) — a variable, function or function template that is explicitly declared static; or,

  • (3.2) — a non-inline variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage; or
  • (3.3) — a data member of an anonymous union.

Annex C (informative) Compatibility, C.1.2 Clause 6: "basic concepts" gives the rationale why this was changed from C:

> 6.5 [also 10.1.7]

> 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 may be used as values during translation in C++, this feature urges programmers to provide an explicit initializer for each const object. This feature allows the user to put const objects in source files that are included in more than one translation unit.

> Effect on original feature: Change to semantics of well-defined feature.

> Difficulty of converting: Semantic transformation.

> How widely used: Seldom.

See also: https://stackoverflow.com/questions/998425/why-does-const-imply-internal-linkage-in-c-when-it-doesnt-in-c

What you likely want to do instead on headers

Explained in detail at: https://stackoverflow.com/questions/177437/what-does-const-static-mean-in-c-and-c/53883715#53883715

  • pre C++17: extern in header, definition in cpp file
  • post C++17: inline variable on header

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionCliffordView Question on Stackoverflow
Solution 1 - C++Ben VoigtView Answer on Stackoverflow
Solution 2 - C++Ciro Santilli Путлер Капут 六四事View Answer on Stackoverflow