Reputation: 2638
The "first attempt" doesn't compile while the second does. Why? What's the difference?
First attempt:
#include <iostream>
int main()
{
constexpr const char text2[] = "hello";
constexpr const char * b = &text2[4]; // error: '& text2[4]' is not a constant expression
std::cout << b << std::endl;
}
Second attempt:
#include <iostream>
int main()
{
constexpr const char * text1 = "hello";
constexpr const char * a = &text1[4];
std::cout << a << std::endl;
return 0;
}
I compile with (g++ version 4.9.2)
g++ -std=c++11 -o main *.cpp
which gives following error
main.cpp: In function 'int main()':
main.cpp:7:40: error: '& text2[4]' is not a constant expression constexpr const char * b = &text2[4]; // error: '& text2[4]' is not a constant expression
Upvotes: 20
Views: 10490
Reputation: 158469
From the draft C++11 standard section 5.19
[expr.const] we can see an address constant expression is (emphasis mine gong forward):
[...] a prvalue core constant expression of pointer type that evaluates to the address of an object with static storage duration, to the address of a function, or to a null pointer value, or a prvalue core constant expression of type std::nullptr_t.
In your first case although "hello"
is a string literal which has static storage duration. It is copied into an array text2
which does not have static storage duration.
While in your second case text1
is a pointer to a string literal which has static storage duration.
Changing your first example to make text2
static (see it live):
constexpr char static text2[] = "hello";
^^^^^^
we no longer get an error.
We can see a string literal has static storage duration from section 2.14.5
[lex.string]:
Ordinary string literals and UTF-8 string literals are also referred to as narrow string literals. A narrow string literal has type “array of n const char”, where n is the size of the string as defined below, and has static storage duration (3.7).
Upvotes: 27