I'm delving into address constant expressions while reading "C++ Programming Language 4th edition" book. It has a short paragraph which describes address constant expressions:
The address of a statically allocated object, such as a global variable, is a constant. However, its value is assigned by the linker, rather than the compiler, so the compiler cannot know the value of such an address constant. That limits the range of constant expressions of pointer and reference type. For example:
constexpr const char* p1 = "asdf"; constexpr const char* p2 = p1; //OK constexpr const char* p2 = p1+2; //error: the compiler does not know the value of p1 constexpr char c = p1[2]; //OK, c=='d'; the compiler knows the value pointed to by p1
I have two questions.
This one is rather trivial - since the compiler doesn't know that address of a static object, then how can it evaluate the second statement during compile time? After all, the fact that the compiler doesn't know the value of
p1+2
, implies thatp1
has to be unknown in the first place, right? g++ 4.8.1 with all the rigorous flags turned on accepts all these statements, though.As exemplified in this topic:
static constexpr int N = 3; int main() { constexpr const int *NP = &N; return 0; }
Here, NP is declared as an address constant-expression, i.e. an pointer that is itself a constant expression. (This is possible when the address is generated by applying the address operator to a static/global constant expression.)
This would also work if we declared N
as simply const
without constexpr
. However, p1
has to be declared explicitly using constexpr
in order to p2
be a valid statement. Otherwise we get:
error: the value of ‘p1’ is not usable in a constant expression
Why is that? "asdf"
is of const char[]
as far as I know.