以下代码正确吗?
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
是这样(是未定义的行为。