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

Solution 1:

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++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: Why does const imply internal linkage in C++, when it doesn't in C?

What you likely want to do instead on headers

Explained in detail at: What does 'const static' mean in C and C++?

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