20

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 
1
  • 1
    I like how you named your variable text2 in the first attempt and test1 in the second attempt. Commented Sep 5, 2017 at 16:05

1 Answer 1

27

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).

Sign up to request clarification or add additional context in comments.

4 Comments

Does const make a constexpr more constant?
@black no, they have different roles for text2 it is not needed but for the pointers it is.
Had to think about it, might as well write it out: in the case of text2, the array gets initialized from the string literal, but the array is a per-instance copy of the string, so taking the address of its fifth element points to a different location in every instance and that is not a constant expression. in the case of text1, the string literal is placed in static space and text1 is set to the same address in every instance of the class, so taking the address of the fifth element points to the same location in every instance and that is a constant expression.
@BlairHoughton that is a good point, I actually realized later on that pointing that out may be helpful. Thank you for making the comment.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.