I know global constexpr variables have internal linkage. so how is it that inline constexpr are introduced with having external linkage? does adding inline just converts internal linakges to external linkages in all cases?
-
1https://en.cppreference.com/w/cpp/language/storage_duration – bolov Jul 11 '22 at 07:13
-
Who said that global constexpr variables have internal linkage? – Jakob Stark Jul 11 '22 at 07:18
-
i thought its internal, maybe confused that with const globals – shiyon sufa Jul 11 '22 at 07:23
3 Answers
There seems to be a little bit of confusion about what "linkage" and "inline" actually means. They are independent (orthogonal) properties of a variable, but nevertheless coupled together.
To inline a variable one declares it inline
. Declaring a constexpr
variable at namescope does not imply inline
[1]. To declare a variable to have internal linkage one declares it static
or more preferrable puts it into an anonymous namespace [2],[3]. For const
and constexpr
(which implies const
) variables there is a special rule, which gives them internal linkage as long as they are non-inline [4].
Because constexpr
variables require an immediate definition [5], you typically want them to be be inline
which allows multiple (equivalent) definitions in multiple translation units:
\\ c.hpp
inline constexpr int c = 0; // define it in header
\\ a.cpp
#include "c.hpp" // c is defined in a.cpp
int a = c; // use it
\\ b.cpp
#include "c.hpp" // c is re-defined in b.cpp
int b = c; // use it
The linkage of c
in that example above is external, because the special rule for const
variables only applies to non-inline variables.
Note that when ommiting the inline
specifier in the example makes each source file get an independent non-inline definition of c
with internal linkage. It will still compile but you have to be careful to not use c
in any inline
functions [6].
You can put inline constexpr
variables into an anonymous namespace or declare it static
to make its linkage internal. If we changed the example above into
\\ c.hpp
namespace {
inline constexpr int c = 0;
};
\\ a.cpp
...
the effects would be almost the same as if ommitin the inline in the original example. Each translation unit gets its own version of the (now inline
d) variable and you have to make sure that you don't use c
in an inline
function.

- 3,346
- 6
- 22
-
1i liked this "For const and constexpr (which implies const) variables there is a special rule, which gives them internal linkage as long as they are non-inline", calling it a special rule and "The linkage of c in that example above is external, because the special rule for const variables only applies to non-inline variables.". thanks – shiyon sufa Jul 11 '22 at 18:10
inline
variable or function make compiler merge* multiple definition into one.
for the same reason, multiple inline constexpr
with same name would has only one instance after link.
then you're accessing the variable in other TU, it's effectively has external linkage.
* it's undefined behavior if the definition are not the same though.
** you cannot declare extern constexpr
, btw

- 10,292
- 2
- 16
- 36
-
Actually you *can* declare `extern constexpr` variables. You just have to define them immediately, that is you cannot make a declaration without definition. – Jakob Stark Jul 18 '22 at 07:15
-
@JakobStark good point. I do mean declare it `extern` without definition (and use it to access another TU's `constexpr` variable). – apple apple Jul 18 '22 at 15:09
I know global constexpr variables have internal linkage
You are missing a few qualifiers (emphasis mine):
Any of the following names declared at namespace scope have internal linkage:
...
non-volatile non-template (since C++14) non-inline (since C++17) non-exported (since C++20) const-qualified variables (including constexpr) (since C++11) that aren't declared extern and aren't previously declared to have external linkage;
...

- 72,283
- 15
- 145
- 224
-
-
-
the premise of the question is false. And I've shown that. Not all global constexpr variables have internal linkage, just the "... , non-inline, ... etc". – bolov Jul 11 '22 at 07:26
-
but thats my question, what does happen that makes the inline version have external linkage? its confusing for me – shiyon sufa Jul 11 '22 at 07:32
-
@bolov That is not true. It is not "just" them. While all "..., non-inline, ..." are have internal, there can be more (the other bullets in your list). In fact there can be inline constexpr variables with either internal or external linkage. – Jakob Stark Jul 11 '22 at 07:34
-
are you talking about const-qualified variables in general right now or any variable that declared at namespace scope? – shiyon sufa Jul 11 '22 at 07:36
-
based on your link, in namespace scope, all variables are internal if the have static keyword. all consts are internal if they dont have extern or ...,inline,... ... – shiyon sufa Jul 11 '22 at 07:41
-
and you said inline constexpr variable can have internal linkage. how? @JakobStark can you write a example of such a variable? – shiyon sufa Jul 11 '22 at 07:43
-
Now I am confused. Maybe I am too tired. @shiyonsufa these are rules, I really don't know how to answer "what does happen that makes the inline version have external linkage" ... it is so because the language says so. What kind of answer do you expect? – bolov Jul 11 '22 at 07:56
-
i see, i thought maybe there be a logical explanation to understand. but if its just rules, then its fine. thanks xD @bolov – shiyon sufa Jul 11 '22 at 08:00