C++:对临时的常量引用
关于 SO 上常量引用的生命周期有几个问题,但我仍然不明白。
这段代码有效吗?
struct S
{
const int &ref;
S( const int &x ) : ref(x) { }
};
int main( )
{
S s( 0 );
// ...
use( s.ref );
// ...
return 0;
}
直觉上我会说不,因为 0
应该在表达式 (S s(0);
) 求值后过期。
然而,GCC 和 CLANG 都可以很好地编译它,没有警告,并且 valgrind 没有检测到任何运行时错误。
我在参考资料中缺少什么?
There are several questions about lifetime of constant reference on SO, but still I don't get it.
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.
However both GCC and CLANG compile it fine, without warnings, and valgrind doesn't detect any runtime error.
What am I missing about references?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
根据 12.2/4 对我来说似乎无效:
临时对象仅在
s
完全构造完成之前有效,而不是在调用use
时有效。Seems invalid to me according to 12.2/4 :
The temporary only gets to live until
s
is fully constructed, not until the point whereuse
is called.正如其他人指出的那样,C++ 标准仅强制编译器在调用构造函数期间保留
0
临时值。实际上,gcc 在main
函数的持续时间内保留临时文件,这会导致程序按预期运行。因此,不会出现警告或运行时错误。但这只是偶然发生的。不要依赖这种行为。
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. In practice gcc keeps the temporary around for the duration of themain
function which results in the program running as expected. For this reason, there are no warnings or runtime errors.But this only works accidentally. Don't rely on this behaviour.
这里要注意的不是 const 而是引用。 const只是静态分析的一个工具。你需要小心参考文献,因为它们会咬人。
有时编译器足够聪明,可以警告您运行时会出现的问题,但有时却不然。无论哪种方式,编译器都不会对此发出警告。
The thing to note here is not the
const
but the reference. The const is just a tool for static analysis. You need to be careful with references because they can bite.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.
这是对代码的另一个调整,甚至 valgrind 也会抱怨:
这通常会将临时数据放入 foo 函数的堆栈帧中,因此当该函数返回时它会被销毁。这类似于返回局部变量的地址。
其他答案已经指出了为什么允许编译器这样做,我的代码只是一个说明。
Here is another tweak to your code that even valgrind complains about:
This normally puts the temporary in the stack frame of the
foo
function, so it gets destroyed when that function returns. 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
不是临时的,而是文字。尝试对您的程序进行这个小更改:我认为引用临时变量的规则仅适用于局部变量,不适用于成员。
0
isn't a temporary, it's a literal. Try this small change to your program:I think the rule for references to a temporary only works for local variables, not members.