为什么编译器允许字符串文字不是const?

Dpp*_*Dpp 9 c c++ memory standards

内存中的文字究竟在哪里?(见下面的例子)

我不能修改文字,所以它应该是一个const char*,虽然编译器允许我使用char*,即使有大多数编译器标志也没有警告.

虽然const char*类型的隐式转换为char*类型给了我一个警告,见下文(在GCC上测试,但它在VC++ 2010上的行为类似).

另外,如果我修改一个const char的值(下面有一个技巧,GCC会更好地给我一个警告),它没有给出任何错误,我甚至可以修改并在GCC上显示它(尽管我猜它仍然是未定义的行为,我想知道为什么它没有对文字做同样的事情).这就是为什么我问这些文字存储在哪里,以及哪些更常见的const应该存储?

const char* a = "test";
char* b = a; /* warning: initialization discards qualifiers 
  from pointer target type (on gcc), error on VC++2k10 */

char *c = "test"; // no compile errors
c[0] = 'p'; /* bus error when execution (we are not supposed to 
  modify const anyway, so why can I and with no errors? And where is the 
  literal stored for I have a "bus error"? 
  I have 'access violation writing' on VC++2010 */

const char d = 'a';
*(char*)&d = 'b'; // no warnings (why not?)
printf("%c", d);  /* displays 'b' (why doesn't it do the same
  behavior as modifying a literal? It displays 'a' on VC++2010 */
Run Code Online (Sandbox Code Playgroud)

hrn*_*rnt 12

C标准不禁止修改字符串文字.它只是表示如果尝试,行为是不确定的.根据C99的基本原理,委员会中有人希望字符串文字可以修改,因此标准没有明确禁止它.

请注意,C++中的情况不同.在C++中,字符串文字是const char的数组.但是,C++允许从const char*到char*的转换.不过,该功能已被弃用.

  • +1,从`const char*`到`char*`的转换是标准,以保持与C和C库的兼容性.许多库都使用了只读为`char*`的参数(在将`const`添加到C之前和之后).为了允许用户在文字(或指向文字的指针)上调用这些函数,添加了转换. (3认同)
  • 实际上,C标准禁止修改字符串文字,因为行为是*undefined*而不是*implementation-defined*; 依赖于修改的代码不是C,而是用类似C语言但不兼容的语言编写的 (3认同)