C中的临时对象 [英] Temporary Objects in C

查看:38
本文介绍了C中的临时对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C11中,定义了临时寿命:

C11 6.2.4p8:具有结构或联合类型的非左值表达式,其中结构或联合包含具有数组类型的成员(递归包括所有包含的结构和联合的成员)是指具有自动存储期限和临时生存期的对象.36)当表达式被求值并且其初始值为表达式的值时,其生命周期开始.当包含完整表达式或完整声明符的求值结束时,其生存期结束.任何试图使用临时生存期修改对象的尝试都会导致未定义的行为.

我想知道为什么这仅适用于具有数组类型成员的结构或联合类型的右值.数组有什么特别之处?

  struct x {int xx;};结构y {int yy [1];};(结构x){42};//*不是*临时对象(结构y){{42}};//一个临时对象 

为什么第一个对象不是临时对象,而第二个对象是临时对象?

解决方案

此限制仅适用于包含数组的临时对象的原因是,该限制仅与包含数组的临时对象相关-当您有未命名的non-lvalue对象不包含数组,因此无法从该对象获取地址;明确禁止使用& .但是,当对象包含一个数组,并且按名称访问该数组时,您将隐式获取该数组的第一个元素的地址.在C11之前,尝试对该指针执行任何操作都是未定义的行为.使用C11,您现在可以使用对象(和指针),而无法对其进行修改.


请注意,您在问题中使用复合文字的示例是 NOT 临时对象-复合文字是左值,因此可以获取其地址,并具有静态存储期限.

获得临时对象的主要方式是当您具有返回struct(或并集)类型的函数时-调用此类函数时,返回的值是临时对象.由于它不是左值,因此不能在其上使用& ,但是如果它包含数组,则可以使用数组名称,这将隐式地衰减为指向该数组第一个指针的指针.元素.

In C11 the term temporary lifetime was defined:

C11 6.2.4p8: A non-lvalue expression with structure or union type, where the structure or union contains a member with array type (including, recursively, members of all contained structures and unions) refers to an object with automatic storage duration and temporary lifetime. 36) Its lifetime begins when the expression is evaluated and its initial value is the value of the expression. Its lifetime ends when the evaluation of the containing full expression or full declarator ends. Any attempt to modify an object with temporary lifetime results in undefined behavior.

I am wondering why this only applies to rvalues of structure or union type which have a member of type array. What is so special about arrays?

struct x { int xx; };
struct y { int yy[1]; };

(struct x)   { 42 };    // *not* a temporary object
(struct y) { { 42 } };  // a temporary object

Why should the first object not be a temporary one while the second is?

解决方案

The reason the restriction only applies to temporary objects that contain arrays is because the restriction is only relevant for temporary objects that contain arrays -- when you have an unnamed non-lvalue object that does NOT contain an array, you can't get an address from the object; using & is explicitly disallowed. However, when the object contains an array, and you access that array by name, you're implicitly getting the address of the first element of the array. Prior to C11, trying to do ANYTHING with that pointer was undefined behavior. With C11, you can now use the object (and the pointer), you just cannot modify it.


Note that the examples you have in the question (with compound literals) are NOT temporary objects -- compound literals are lvalues, so can have their address taken, and have static storage duration.

The main way you get temprary objects is when you have a function that returns a struct (or union) type -- when you call such a function, the returned value is a temprary object. Since it is not an lvalue, you can't use & on it, but if it contains an array, you can use the array name, and that will implicitly decay to a pointer to the array's first element.

这篇关于C中的临时对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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