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
The primary difference between const and constexpr variables is that the initialization of a const variable can be deferred until run time. A constexpr variable must be initialized at compile time. All constexpr variables are const .
constexpr creates a compile-time constant; const simply means that value cannot be changed.
But we can change the value of pointer as it is not constant and it can point to another constant char. char* const says that the pointer can point to a char and value of char pointed by this pointer can be changed. But we cannot change the value of pointer as it is now constant and it cannot point to another char.
So you should definitely use static constexpr in your example. However, there is one case where you wouldn't want to use static constexpr . Unless a constexpr declared object is either ODR-used or declared static , the compiler is free to not include it at all.
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).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With