我相信您会问为什么将文字放在
只读存储器,而不是关于链接器执行此操作的技术细节和
该或禁止某某标准的法律细节。
当修改字符串文字工作时,它会导致一些细微的错误
即使没有字符串合并(我们有理由
如果我们决定允许修改,则不允许)。当你看到类似的代码时
char *str="Hello";
.../* some code, but str and str[...] are not modified */
printf("%s world\n", str);
很自然地得出结论,您知道将要打印什么,
因为str(及其内容)没有在特定的
位置,介于初始化和使用之间。
然而,如果字符串字面量是可写的,你不知道任何
more: str[0] 可以在以后被覆盖,在这个代码中或者在一个
深度嵌套的函数调用,以及再次运行代码时,
char *str="Hello";
不再保证str 的内容。正如我们
期望,这个初始化被实现为移动已知的地址
在链接时间进入str 的位置。它不检查str
包含“Hello”并且它不分配它的新副本。然而,
我们理解此代码将str 重置为“Hello”。很难
克服这种自然的理解,很难推理
无法保证的代码。当你看到类似的表达
x+14,如果您不得不考虑可能会覆盖 14 怎么办
在其他代码中,所以它变成了 42?字符串也有同样的问题。
这就是不允许修改字符串文字的原因,无论是在
标准(不要求及早发现故障)和
实际目标平台(提供检测潜力的奖励
错误)。
我相信许多解释这件事的尝试都受到了
最糟糕的循环推理。该标准禁止写入
文字,因为编译器可以合并字符串,或者可以将它们放在
在只读存储器中。它们被放置在只读存储器中以捕获
违反标准。合并文字是有效的,因为
标准禁止...这是您要求的一种解释吗?
让我们看看其他
语言。 Common Lisp standard
使文字的修改未定义的行为,即使
之前 Lisp 的历史与 C 的历史非常不同
实施。这是因为可写字面量是逻辑上的
危险的。语言标准和内存布局仅反映了这一点
事实。
Python 语言只有一个地方有类似的东西
“写入文字”可能会发生:参数默认值,而这
事实confuses people all the time。
你的问题被标记为C++,我不确定它的当前状态
关于隐式转换到非常量char*:如果它是
转换,是否已弃用?我希望其他答案能够提供
在这一点上完全启蒙。当我们谈论其他语言时
在这里,让我提一下普通 C。这里,字符串文字是 not const,
并且要问的一个等效问题是 为什么我不能修改字符串
文字(而有更多经验的人会问,为什么
如果我不能修改它们,字符串文字非常量?)。然而
尽管存在这种差异,上述推理完全适用于 C。