Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

constexpr const char * vs constexpr const char[]

Tags:

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  
like image 398
Lukáš Bednařík Avatar asked Nov 13 '15 12:11

Lukáš Bednařík


People also ask

What is difference between const and constexpr?

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 .

What does constexpr const mean?

constexpr creates a compile-time constant; const simply means that value cannot be changed.

What is the difference between const char and char?

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.

Should constexpr be static?

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.


1 Answers

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

like image 74
Shafik Yaghmour Avatar answered Sep 19 '22 12:09

Shafik Yaghmour