为什么C中的复合文字可以修改 [英] Why are compound literals in C modifiable

查看:107
本文介绍了为什么C中的复合文字可以修改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通常会将不可修改"与字面量联系起来

One does usually associate 'unmodifiable' with the term literal

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

但是,当使用复合文字时,我很快发现它们是完全可修改的(查看生成的机器代码,您会看到它们被压入堆栈了):

However when using compound literals, I quickly discovered they are completely modifiable (and looking at the generated machine code, you see they are pushed on the stack):

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

我正在使用clang-703.0.29进行编译.这两个示例不应该生成完全相同的机器代码吗?复合字面量是否可以修改,真的是一个字面量吗?

I'm compiling with clang-703.0.29. Shouldn't those two examples generate the exact same machine code? Is a compound literal really a literal, if it's modifiable?

一个更简短的例子是:

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

推荐答案

复合文字是左值,其元素的值是可修改的.如果是

A compound literal is an lvalue and values of its elements are modifiable. In case of

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

您正在修改合法的复合文字.

you are modifying a compound literal which is legal.

C11-§6.5.2.5/4:

C11-§6.5.2.5/4:

如果类型名称指定了一个未知大小的数组,则该大小由6.7.9中指定的初始化程序列表确定,并且复合文字的类型是完整数组类型的类型 .否则(当类型名称指定对象类型时),该类型 复合文字的含义是由类型名称指定的. 无论哪种情况,结果都是左值.

If the type name specifies an array of unknown size, the size is determined by the initializer list as specified in 6.7.9, and the type of the compound literal is that of the completed array type. Otherwise (when the type name specifies an object type), the type of the compound literal is that specified by the type name. In either case, the result is an lvalue.

可以看出,复合文字的类型是完整的数组类型,并且是左值,因此与字符串文字

As it can be seen that the type of compound literal is a complete array type and is lvalue, therefore it is modifiable unlike string literals

标准还提到

§6.5.2.5/7:

§6.5.2.5/7:

字符串文字和具有const限定类型的复合文字不需要指定不同的对象. 101

进一步说:

11示例4可以通过以下结构指定只读复合文字:

11 EXAMPLE 4 A read-only compound literal can be specified through constructions like:

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

12示例5以下三个表达式具有不同的含义:

12 EXAMPLE 5 The following three expressions have different meanings:

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

第一个始终具有静态存储期限,并且类型数组为char,但无需修改;当最后两个出现在函数主体中时,它们具有自动存储持续时间,而其中的前一个 两个是可以修改的.

The first always has static storage duration and has type array of char, but need not be modifiable; the last two have automatic storage duration when they occur within the body of a function, and the first of these two is modifiable.

13例6与字符串文字一样,const限定的复合文字可以放入只读存储器中,甚至可以共享.例如

13 EXAMPLE 6 Like string literals, const-qualified compound literals can be placed into read-only memory and can even be shared. For example,

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

如果共享文字的存储空间,则

可能会产生1.

might yield 1 if the literals’ storage is shared.

这篇关于为什么C中的复合文字可以修改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆