可以修改字符串文字和非字符串非复合文字吗?

时间:2017-08-14 23:22:08

标签: c literals string-literals

字符串文字是左值,它打开门以修改字符串文字。

来自C in a Nutshell:

  

在C源代码中,文字是表示固定值的标记,可以是整数,浮点数,字符或串。文字的类型由其值和符号决定。   这里讨论的文字不同于C99标准中引入的复合文字。复合文字是普通的可修改对象,类似于变量。

     

虽然 C并不严格禁止修改字符串文字,但您不应尝试这样做。首先,编译器,将字符串文字视为常量,可以将其置于只读存储器中,在这种情况下,尝试的写操作会导致错误。另一方面,如果程序中使用了两个或多个相同的字符串文字,编译器可能会将它们存储在同一位置,因此当您访问另一个时,修改一个会导致意外的结果。

  1. 第一段说" C中的文字表示固定值"。

    • 这是否意味着不应修改文字(复合文字除外)?

    • 由于字符串文字不是复合文字,是否应修改字符串文字?

  2. 第二段说" C并没有严格禁止 修改字符串文字"虽然编译器有。那应该是一个字符串 文字被修改?
  3. 这两段是否相互矛盾?我怎么理解他们?

  4. 是否可以修改既不是复合文字也不是字符串文字的文字?

3 个答案:

答案 0 :(得分:8)

来自C标准(6.4.5字符串文字)

  

7未指明这些阵列是否与它们不同   元素具有适当的值。 如果程序尝试   修改这样的数组,行为是未定义的。

至于你的陈述。

  

第二段说“C不严格禁止修改   字符串文字“虽然编译器这样做。所以字符串文字应该是   改性?

然后编译器不会修改字符串文字。它们可以将相同的字符串文字存储为一个数组。

正如 @ o11c 在附件J(资料性)可移植性问题的评论中指出的那样有

  

J.5公共扩展

     

1以下扩展名被广泛使用   许多系统,但不能移植到所有实现。该   包含任何可能导致严格符合的扩展名   程序变为无效会导致实现不一致。   此类扩展的示例是新关键字,额外库函数   在标准头文件中声明,或者使用名称的预定义宏   不要以下划线开头。

     

J.5.5可写字符串文字

     

1字符串文字是可修改的(在这种情况下,相同的字符串   文字应该表示不同的对象)(6.4.5)。

答案 1 :(得分:5)

不要修改字符串文字。将它们视为char const[]。 字符串文字实际上是char const[](修改它们导致未定义的行为),但由于遗留原因它们真的是char [],这意味着编译器不会阻止你写入它们,但是你的程序将会如果你这样做,仍然是不确定的。

答案 2 :(得分:4)

并且更实际地说 - 不是每个硬件平台都提供保护只读存储对象的存储器位置的机制。它必须被定义为UB。有3种可能的选择:

  1. 文字(以及更常见的常量对象)保存在RAM中,但硬件不提供内存保护机制。没有什么能阻止程序员写到这个位置

  2. 文字(和常量对象)保存在RAM中但硬件确实提供了内存保护机制 - 您将获得段错误

  3. 只读数据存储在只读存储器中(例如uC FLASH)。您可以尝试编写它,但它没有效果(例如ARM)。没有提出硬件异常