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



以下代码正确吗?

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的错误是:"正在初始化":无法从"常量字符 [11]"转换为"字符 [11]"。

所以不清楚"S"和"S1"之间的关系是什么?它们是否引用相同的字符串文字?

定义

static const char * s1 = s;

等于

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

也就是说,你s1指出s的第一个元素,仅此而已。没有"复制"。

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

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

我的第一个想法是"s"只存在于编译时

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

">

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

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

第 2 行在没有 'const' 的情况下无法编译:

如果没有const_cast,你就无法做到这一点——但无论如何你都不会想要,因为修改原始const变量(s是这样(是未定义的行为。

最新更新