Difference between constexpr and static constexpr global variable - c++

In the C++11 standard, what is the difference between constexpr and static constexpr global variables when defined in a header? More specifically, when multiple translation units include the same header, which declaration (if any) is guaranteed to define the same variable across the translation units?
e.g.,
cexpr.h:
#ifndef CEXPR_H
#define CEXPR_H
constexpr int cint = 1;
static constexpr int scint = 1;
#endif
a.cpp:
#include "cexpr.h"
b.cpp:
#include "cexpr.h"

In your current example there is no difference: On variable declarations, constexpr implies const, and a const variable at namespace scope has internal linkage by default (so adding static does not change anything).
In C++14, you cannot declare a variable as constexpr and have it have external linkage unless you only ever do this in one single translation unit. The reason is that constexpr variables require an initializer, and a declaration with initializer is a definition, and you must only have a single definition.
However, what you can do is use a normal integral constant, which you can declare (not define) as extern, and in the translation unit where it is defined it can even be used as a constant expression:
lib.h:
extern const int a;
lib.cpp:
#include "lib.h"
const int a = 10;
int b[a] = {1, 2, 3}; // OK in this translation unit
In C++17, there is a new feature "inline variables" which lets you say:
inline constexpr int a = 10;
And this is an "inline definition" that can appear repeatedly, and each definition defines the same entity (just like all the other "inline" entities in the language).

I think this article explains more clear. 6.8 — Global constants and inline variables
Because const globals have internal linkage, each .cpp file gets an independent version of the global variable that the linker can’t see. In most cases, because these are const, the compiler will simply optimize the variables away.
The term “optimizing away” refers to any process where the compiler optimizes the performance of your program by removing things in a way that doesn’t affect the output of your program. For example, lets say you have some const variable x that’s initialized to value 4. Wherever your code references variable x, the compiler can just replace x with 4 (since x is const, we know it won’t ever change to a different value) and avoid having to create and initialize a variable altogether.
So, the "cint " and "scint" are all internal linkage variables.
The best practice to define global variable after C++ 17:
inline constexpr double pi = 0;
Working Mechanism:
C++17 introduced a new concept called inline variables. In C++, the term inline has evolved to mean “multiple definitions are allowed”. Thus, an inline variable is one that is allowed to be defined in multiple files without violating the one definition rule. Inline global variables have external linkage by default.
Inline variables have two primary restrictions that must be obeyed:
1) All definitions of the inline variable must be identical (otherwise, undefined behavior will result).
2) The inline variable definition (not a forward declaration) must be present in any file that uses the variable.
The compiler will consolidate all inline definitions into a single variable definition. This allows us to define variables in a header file and have them treated as if there was only one definition in a .cpp file somewhere. These variables also retain their constexpr-ness in all files in which they are included.

If you can, prefer the static constexpr because with the constexpr it depends on the toolchain how likely it will get done on compile-time. Gcc is most aggressive, MSVS least aggressive and clang is in between.
Instead of leaving some values up to optimizer to decide it will do it at compile-time be more explicit and force it.
Reference:
https://www.youtube.com/watch?v=4pKtPWcl1Go

Related

inline constexpr have external linkage? [duplicate]

This question already has answers here:
constexpr variable at namespace scope with and without explicit inline definition
(2 answers)
Closed 7 months ago.
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?
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 inlined) variable and you have to make sure that you don't use c in an inline function.
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
I know global constexpr variables have internal linkage
You are missing a few qualifiers (emphasis mine):
internal linkage
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;
...

Why are non member static constexpr variables not implicitly inline?

In C++17 we got inline variables and I have assumed that global constexpr variables are implicitly inline.
But apparently this is true only for static member variables.
What is the logic/technical limitation behind this?
source:
A static member variable (but not a namespace-scope variable) declared constexpr is implicitly an inline variable.
The reason why constexpr static data members were made implicitly inline was to solve a common problem in C++: when defining a class-scoped constant, one was previously forced to emit the definition in exactly one translation unit, lest the variable be ODR-used:
// foo.h
struct foo {
static constexpr int kAnswer = 42;
};
// foo.cpp
// a linker error will occur if this definition is omitted before C++17
#include "foo.h"
constexpr int foo::kAnswer;
// main.cpp
#include "foo.h"
#include <vector>
int main() {
std::vector<int> bar;
bar.push_back(foo::kAnswer); // ODR-use of 42
}
In such cases, we usually care only about the value of the constant, not its address; and it's convenient for the compiler to synthesize a unique location for the constant in case it really is ODR-used, but we don't care where that location is.
Thus, C++17 changed the rules so that the out-of-line definition is no longer required. In order to do so, it makes the declaration of foo::kAnswer an inline definition, so that it can appear in multiple translation units without clashing, just like inline functions.
For namespace-scope constexpr variables (which are implicitly static, and therefore have internal linkage, unless declared extern) there is no similar issue. Each translation unit has its own copy. inline, as it's currently specified, would have no effect on such variables. And changing the existing behaviour would break existing programs.
The point here is that constexpr int x = 1; at namespace scope has internal linkage in C++14.
If you make it implicitly inline without changing the internal linkage part, the change would have no effect, because the internal linkage means that it can't be defined in other translation units anyway. And it harms teachability, because we want things like inline constexpr int x = 1; to get external linkage by default (the whole point of inline, after all, is to permit the same variable to be defined in multiple translation units).
If you make it implicitly inline with external linkage, then you break existing code:
// TU1
constexpr int x = 1;
// TU2
constexpr int x = 2;
This perfectly valid C++14 would become an ODR violation.

Why does cppreference define type_traits xxx_v shortcuts as inline constexpr and not just constexpr?

Why does cppreference define type_traits xxx_v shortcuts as inline constexpr and not just constexpr?
For example, see is_integral_v:
template< class T >
inline constexpr bool is_integral_v = is_integral<T>::value;
Is this just a matter of style or is there some difference in behavior? As far as I know constexpr variables are implicitly inline.
Edit: Looking at the draft of the latest standard, it also uses inline constexpr. The question actually applies to the standard, then.
[dcl.constexpr]/9
A constexpr specifier used in an object declaration declares the object as const.
[basic.link]/3.2
A name having namespace scope has internal linkage if it is the name of
-a non-inline variable of non-volatile const-qualified type that is neither explicitly declared extern nor previously declared to have external linkage
Without inline specifier, is_integral_v would have internal linkage. This could be problematic if you compared two pointers to this same variable name taken in different translation unit.
Nota Bene: the inline specifier is redundant with constexpr only if the variable is a class static data member.
Following an exemple of easy violation of the one definition rule that could happen if is_integral_v where not inline.
bad_type_trait.h
template<class T>
constexpr auto bad_is_integral_v=std::is_integral<T>::value;
my_header.h
#include "bad_type_trait.h"
void f(const bool& x);
inline void g()
{
f(bad_is_integral_v<int>);
//g ODR use the static variable bad_is_integral_v.
//"ODR use" approximate definition is:
// the variable is refered by its memory address.
}
source1.cpp
#include "my_header.h"
void my_func1(){
g(); //the definition of g in this translation unit.
}
source2.cpp
#include "my_header.h"
void my_func2(){
g(); //is not the same as the definition of g in this translation unit.
}
In the two translation units, the variable bad_is_integral_v is instantiated as separate static variables. The inline function g() is defined in these two translation units. Inside the definition of g(), the variable bad_is_integral_v is ODR used, so the two definitions of g() are different, which is a violation of the one definition rule.
[basic.link]/3.2 applies to names of "a non-inline variable of non-volatile const-qualified type". A variable template isn't a variable, just like a class template isn't a class, a function template isn't a function, and a cookie cutter isn't a cookie. So that rule doesn't apply to the variable template is_integral_v itself.
A variable template specialization is a variable, however, so there are some questions about whether that rule gives it internal linkage. This is core issue 1713, the direction of which is that the rule is not applicable.
Core issue 1713, however, wasn't resolved in time for C++17. So LWG decided to simply plaster inline all over the variable templates just to be safe, because they don't hurt, either.

Why is "inline" required on static inline variables?

C++17 allows static member variables to be defined thus:
class X {
public:
static inline int i = 8;
};
What is the rationale behind requiring the inline specification? Why not simply allow programmers to write
static int i = 8;
in the class?
Without inline, it's explicitly stated as only a declaration. As specified in [class.static.data]/2
The declaration of a non-inline static data member in its class
definition is not a definition and may be of an incomplete type other
than cv void. The definition for a static data member that is not
defined inline in the class definition shall appear in a namespace
scope enclosing the member's class definition.
The rationale is most probably to keep legacy code intact and valid. Recall that we could initialize integral constants in the class definition itself since about forever. But odr-using them still required an out-of-class definition in some translation unit.
So to makes such variables implicitly inline could be problematic in existing codebases. The committee is always thinking about backwards compatibility when core language features are added.
For instance, consider this valid C++03 class definition:
struct foo {
static const int n = 3;
double bar[n];
};
n can be used as a constant expression to define the extent of bar, and it's not considered an odr-use. Nowadays we'd write it as constexpr1, however that above is still valid. But there may be cases were n would have to be odr-used (imagine its address taken, or a reference bound to it, etc). They are probably not many, and probably not common, but certain API's have crazy requirements that would end up necessitating this
const int foo::n;
to appear in some translation unit.
Now, if static inline int i = 8; was suddenly implicitly inline, the definition above (that is in an existing code base) would be an odr-violation. Now previously well-formed code, is ill-formed. So it's best to allow only explicit inline to take effect here, since only new code will actually have it.
1 One could argue that static constexpr variables may have the same issue (and yet they are implicitly inline). But IIRC their original wording allowed this change without potentially breaking existing code. It was essentially already "inline" by everything but name.

What is the difference between these three statements?

What is the difference between these three statements?
static const int foo = 42;
const int foo = 42;
#define foo 42
2) const int foo = 42;
This is an int variable whose value you can't change.
1) static const int foo = 42;
This is the same as 2), but it's only visible in the source code file that it's in. So you can't use it in another .cpp file for example if you compile them separately and then link together. By using static with variables and functions you allow the compiler to optimize them better because the compiler can rely on that it knows all situations where that variable or function is used. The word static has different meanings in different situations, but this is its behavior if you use it in the global level. If you use this inside a function, it has a different meaning. Then it means that this variable is only initialized once and it stays in the memory no matter how many times the code execution passes that definition. This has more meaning if you don't use const at the same time, because then you can change the value of the variable and it will "remember" that value even when you exit the part of code where that variable is visible (called "scope") and re-enter it.
3) #define foo 42
This is a precompiler macro. So the precompiler will substitute all "foo"s with the number 42 before giving to code to the actual compiler. Some years ago people used this approach because it was faster than const variables, but nowadays they are equally fast.
static const int foo = 42;
What this does depends on where it is found and what language you are using:
If this is a declaration at namespace scope (in C++) or file scope (in C), then it declares and defines a const-qualified object named foo that has internal linkage (this means that the name foo only refers to this object in the current translation unit, not in other translation units).
If this is a declaration at function scope (in C or C++), then it declares and defines a const-qualified object named foo that has no linkage (locally declared variables don't have linkage) and the lifetime of that object is the duration of the program (this means that in every call to the function, foo refers to the same object).
If this is C++ and this is a declaration inside of a class, then it declares but does not define a const-qualified static data member named foo that has external linkage (this means that the name foo (in this case, when qualified with the class name) refers to the same object when used in any translation unit).
const int foo = 42;
What this does depends on what language you are using and where the declaration appears. If the declaration is at namespace or file scope, then
In C++ this declares and defines a const-qualified object named foo that has internal linkage (the const implies internal linkage in C++).
In C this declares and defines a const-qualified object named foo that has external linkage (the const does not imply internal linkage in C).
In both C++ and C, if this declaration is at function scope, then this declares and defines a const-qualified local variable named foo that has no linkage.
#define foo 42
This does not define an object; it defines a macro named foo that is replaced by the token sequence consisting of a single token, 42.
The const modifier is used to specify that foo is a constant. i.e. After initialisation, its value may not be changed.
The static keyword is used to to tell the compiler that the value of the variable you're declaring as static should be retained even when it goes out of scope. This means that if you declare a variable static inside a function, it's value will be remembered even after the function returns (unlike automatic variables). It's also used to tell the compiler that a variable is visible only within the current unit of compilation. This means if that you declare a top level variable/function static, it's not visible from other files that you're compiling along with this one.
#define is a preprocessor directive that performs textual substitution on all occurrences of (in this case) foo before actual compilation takes place. The compiler doesn't even see foo. It only sees 42.
First two declare a variable called foo, while the third one doesn't declare any variable, it's just an alias of 42.
In C, first one is a file-cope variable, while the second one has external linkage, means it can be referred to from another translation unit!
But in C++, both ( first and second) are same, because in C++ const are static by default; both has internal linkage!
static const int foo = 42;
A constant static variable. The value once initialized can't be changed as long as the variable exists. Being static the variable can't be included in any files even if the file in which it is declared is included. If this is member of a class then only one copy of the variable exists for all the instances of the class.
const int foo = 42;
A constant variable where the value once initialized stays and cant be changed.
#define foo 42
Not a variable but a symbolic constant. so operations like &foo are not allowed. foo only serves as an alias to 42. Unlike others this is processed by the preprocessor .
What does static mean? hint: fgbentr fcrpvsvre
What does const mean? hint: ernq-bayl inevnoyr
What does #define do? In what stage of compilation does it take place? What's that mean for generated code?