正在施放带有“ Int”类型的临时性

Is casting a temporary with type `int` to a reference safe?

本文关键字:类型 临时性 Int 施放带      更新时间:2023-10-16

在以下程序中:

int Func()
{
    int a = { 10 };
    return a;
}
int main()
{  
    int& r = (int&)(const int&)Func();
    r = 5;        
}

r是对int类型的临时性的引用。但是,除非将临时工正常分配给参考,否则临时工会立即被销毁。上面的任务似乎并不正常。在标准C ?

中使用r安全是否安全

简介: C风格的铸件等效于(C 17 [Expr.cast]):

int& r = const_cast<int&>( static_cast<const int&>(Func()) );

在子表达static_cast<const int&>(Func())中,行为由C 17 [Expr.static.cast]/4(其中T是被施放的类型):

如果T是参考类型,则效果与执行 某些发明的临时变量t(11.6)的声明和初始化T t(e);,然后使用临时变量作为转换

的结果

在这种情况下,Tconst int&,因此参考的初始化类似于const int& t(Func());

现在,此代码中有两个问题:

  • 临时类型
  • 涉及的临时寿命

临时类型是const int(C 17 [DCL.Init.ref]/5.2.1.2)。因此,您的代码通过修改常量对象会导致不确定的行为。链接到其他有关此主题的问题

在此答案的其余部分(解决生命周期问题)中,我假设您将r = 5更改为仅读取r的语句。


随着CWG 1299的应用,参考链的行为发生了变化。缺陷于2011年4月提交,并于2017年3月解决。该分辨率未出现在C 17(N4659)中;它仅在C 17个草稿中出现。

该分辨率具有状态DRWP,我对此的理解是,它意味着它追溯适用于C 17,但不适用于C 14(如果某人想确认或纠正这将很棒)。


无论如何,在某些情况下,该决议可以超越参考链。措辞为(n4762 class.temporary/6):

[...]引用绑定到的临时对象,或临时对象,该对象是 glvalue of to to to the the Lifetime bond bodive of to to to to to to bobignt的临时对象。该参考已绑定获得 通过以下一个:

  • [...]
  • a const_caststatic_castdynamic_castreinterpret_cast转换,没有用户定义的转换,这是glvalue操作数,这是指glvalue的一种表达式,它是指操作系统指定的对象,或者涉及其完整对象或完整对象或一个对象

在CWG1299之前,本段仅应用于初始化prvalue的引用,但是现在它可以应用于指定对象是临时对象的任何表达式类别初始化参考的情况。

请注意,在C 17中的暂时性化的作品是,当物质化发生时,prvalue被转换为xvalue,而该xvalue是上面的粗文本所指的glvalue。

现在甚至包含一个示例来确认这一点:

const int& b = static_cast<const int&>(0); //临时int的寿命与b

另一个已删除答案中显示的编译器的行为必须应用于CWG1299的分辨率。