简体   繁体   English

C ++:对临时的常量引用

[英]C++: constant reference to temporary

There are several questions about lifetime of constant reference on SO, but still I don't get it. 关于SO的持续参考的生命周期有几个问题,但我仍然没有得到它。

Is this piece of code valid? 这段代码有效吗?

struct S
{
    const int &ref;
    S( const int &x ) : ref(x) { }
};

int main( )
{
    S s( 0 );
    // ...
    use( s.ref );
    // ...
    return 0;
}

Intuitively I'd say no, since 0 should expire after the expression ( S s(0); ) is evaluated. 直觉上我会说不,因为在表达式( S s(0); )被评估之后0应该到期。

However both GCC and CLANG compile it fine, without warnings, and valgrind doesn't detect any runtime error. 但是GCC和CLANG都编译好了,没有警告,并且valgrind没有检测到任何运行时错误。

What am I missing about references? 我对参考文献缺少什么?

Seems invalid to me according to 12.2/4 : 根据12.2 / 4对我来说似乎无效:

There are two contexts in which temporaries are destroyed at a different point than the end of the fullexpression. 有两种情况,临时表演在不同于完整表达结束时被摧毁。 The first context is when an expression appears as an initializer for a declarator defining an object . 第一个上下文是表达式作为定义对象的声明符的初始值设定项 In that context, the temporary that holds the result of the expression shall persist until the object's initialization is complete . 在该上下文中,保存表达式结果的临时值将持续存在,直到对象的初始化完成

The temporary only gets to live until s is fully constructed, not until the point where use is called. 临时只能在s完全构建之前生存,直到调用use

As others have pointer out, the C++ standard only forces the compiler to keep the 0 temporary around for the duration for calling the constructor. 当其他人指出时,C ++标准只强制编译器在调用构造函数的过程中保持0临时。 In practice gcc keeps the temporary around for the duration of the main function which results in the program running as expected. 在实践中,gcc在main函数的持续时间内保持临时性,这导致程序按预期运行。 For this reason, there are no warnings or runtime errors. 因此,没有警告或运行时错误。

But this only works accidentally. 但这只是偶然的。 Don't rely on this behaviour. 不要依赖这种行为。

The thing to note here is not the const but the reference. 这里要注意的不是const而是参考。 The const is just a tool for static analysis. const只是静态分析的工具。 You need to be careful with references because they can bite. 您需要小心引用,因为它们可以咬人。

int& f()
{
    int i = 2;
    return i;
}

Sometimes the compiler is smart enough to warn you about issues that would show up at run time, but sometimes it's not. 有时,编译器足够智能,可以警告您在运行时出现的问题,但有时却不是。 Either way the compiler doesn't have to warn you about this. 无论哪种方式,编译器不必就此发出警告。

Here is another tweak to your code that even valgrind complains about: 这是对你的代码的另一个调整,甚至valgrind抱怨:

#include <iostream>

struct S
{
    const int &ref;
    S( const int &x ) : ref(x) { }
};

S* foo()
{
    return new S(0);
}

int main( )
{
    S* s = foo();
    std::cout << s->ref << std::endl;
    return 0;
}

This normally puts the temporary in the stack frame of the foo function, so it gets destroyed when that function returns. 这通常将临时放在foo函数的堆栈帧中,因此当该函数返回时它会被销毁。 This is similar to returning the address of a local variable. 这类似于返回局部变量的地址。

The other answers have pointed out why the compiler is allowed to do this, my code is just an illustration. 其他答案指出了为什么允许编译器这样做,我的代码只是一个例子。

0 isn't a temporary, it's a literal. 0不是临时的,它是文字的。 Try this small change to your program: 尝试对您的程序进行这一小改动:

struct S 
{
    const int &ref;
    S( const int &x ) : ref(x) { }
};

int f()
{
    return 0;
}

int main( )
{
    S s( f() );
    // ...
    use( s.ref );
    // ...
    return 0;
}

I think the rule for references to a temporary only works for local variables, not members. 我认为引用临时的规则仅适用于局部变量,而不适用于成员。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM