以下代码正确吗?
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”之间的关系是什么?他们引用相同的字符串文字吗?
答案 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
是一种不确定的行为)