constexpr const char * vs constexpr const char[]

constexpr const char * vs constexpr const char[]

本文关键字:constexpr char const vs      更新时间:2023-10-16

"第一次尝试"不编译,而第二次尝试编译。为什么?有什么区别?

第一次尝试:

#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;
}

第二次尝试:

#include <iostream>
int main()
{
constexpr const char * text1 = "hello";
constexpr const char * a = &text1[4];
std::cout << a << std::endl;
return 0;
}

我使用(g++版本4.9.2)进行编译

g++ -std=c++11 -o main *.cpp

其给出以下错误

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  

从C++11标准草案5.19[expr.const]中,我们可以看到一个地址常量表达式是(emphasis mine gong forward):

[…]一个prvalue核心常量表达式的指针类型,计算结果为具有静态存储持续时间、函数地址或null指针值,或类型为的prvalue核心常量表达式std::nullptr_t。

在第一种情况下,尽管"hello"是一个具有静态存储持续时间的字符串文字。它被复制到没有静态存储持续时间的阵列text2中。

而在第二种情况下,text1是指向具有静态存储持续时间的字符串文字的指针。

更改您的第一个示例以使text2静态(实时查看):

constexpr char static text2[] = "hello";
               ^^^^^^

我们不再有错误。

我们可以从2.14.5[lex.string]:部分看到字符串文本具有静态存储持续时间

还引用了普通字符串文字和UTF-8字符串文字到作为窄字符串文字。窄字符串文字的类型为"array"of n const char",其中n是如下定义的字符串的大小,并且具有静态存储持续时间(3.7)