-->

为什么在C修改复合文字为什么在C修改复合文字(Why are compound literals i

2019-05-12 10:10发布

一个人通常关联“不可修改的”与术语字面

char* str = "Hello World!";
*str = 'B';  // Bus Error!

然而,使用复合文字的时候,我很快就发现(,你看他们都压入堆栈,并在生成机器码锁定)它们是完全可修改:

char* str = (char[]){"Hello World"};
*str = 'B';  // A-Okay!

我与编译clang-703.0.29 。 如果不是这两个例子产生完全相同的机器代码? 是一种复合文字真的文字,如果它的修改?

编辑:更短的例子是:

"Hello World"[0] = 'B';  // Bus Error!
(char[]){"Hello World"}[0] = 'B';  // Okay!

Answer 1:

的化合物,文字是一个左值和它的元素的值是可修改的。 的情况下

char* str = (char[]){"Hello World"};
*str = 'B';  // A-Okay!  

要修改复合文字是合法的。

C11-§6.5.2.5/ 4:

如果类型名称指定未知大小的阵列,如在6.7.9所指定的大小由初始值设定表确定的, 并且该化合物文字的类型是所完成的阵列型的 。 否则(当类型名称指定的对象类型),化合物文字的类型是由类型名指定。 在任一情况下,结果是左值

如可以看出, 化合物文字的类型是一个完整的阵列型和是左值,因此它不同于字符串文字修改

标准还提到,

§6.5.2.5/ 7:

字符串常量,并用常量限定类型复合文字,不必指定不同的对象。 101

此外,它说:

11实施例4只读化合物字面可以通过像结构来指定:

 (const float []){1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6} 

12实施例5下面三个表达式具有不同的含义:

 "/tmp/fileXXXXXX" (char []){"/tmp/fileXXXXXX"} (const char []){"/tmp/fileXXXXXX"} 

第一总是具有静态存储持续时间,且类型的阵列char ,但不必是可修改的 ; 最后两个具有自动存储持续时间时发生的功能的主体内它们,并且第一这两的是可修改的

13个实施例6像字符串常量,const限定复合文字可以被置于只读存储器,甚至可以共享。 例如,

 (const char []){"abc"} == "abc" 

如果文字存储共享可能产生1。



文章来源: Why are compound literals in C modifiable