用constexpr初始化非常量静态字符串

时间:2019-04-08 11:51:24

标签: c++ c++17

以下代码正确吗?

constexpr char s[] = "a, bb, ccc";
static const char * s1 = s;
char * s2 = const_cast<char *>(s1);
s2[5] = 'x';

我的第一个想法是's'仅在编译时存在,并且's1'可能是's'的某种形式的副本,但由于它的第2行没有'const'才能进行编译,因此可能不太正确:

static char * s1 = s;

MSCV2017的错误是:'initializing':无法从'const char [11]'转换为'char [11]'。

所以不清楚“ s”和“ s1”之间的关系是什么?他们引用相同的字符串文字吗?

2 个答案:

答案 0 :(得分:2)

定义

static const char * s1 = s;

等于

static const char * s1 = &s[0];

也就是说,您使s1指向s的第一个元素,仅此而已。没有进行“复制”。

这就是为什么您不能使用指向非常量(即char *)的指针的原因,因为s1将指向常量数据。

这也是为什么s2[5] = 'x'会在尝试修改常量数据时导致未定义行为的原因。

答案 1 :(得分:1)

  

我的第一个想法是's'仅在编译时存在

否,它在运行时也存在。 constexpr并不意味着“仅在编译时”。这里的意思是“ {s必须使用常量表达式初始化”(基本上是编译时常量),这意味着它本身也可以在常量表达式中使用。

  

's1'可能是's'的某种副本

s1仅指向s数组的第一个字符。它不是数组内容的副本。

  

第2行没有'const'不会编译:

如果没有const_cast,您将无法做到这一点-但您还是不会想要,因为修改原始的const变量(s是一种不确定的行为)