【发布时间】:2014-10-23 01:24:42
【问题描述】:
我知道如果一个临时对象绑定到构造函数的初始化列表中的引用成员,该对象将在构造函数返回时被销毁。
不过,请考虑以下代码:
#include <functional>
#include <iostream>
using callback_func = std::function<int(void)>;
int
func(const callback_func& callback)
{
struct wrapper
{
const callback_func& w_cb;
wrapper(const callback_func& cb) : w_cb {cb} { }
int call() { return this->w_cb() + this->w_cb(); }
};
wrapper wrp {callback};
return wrp.call();
}
int
main()
{
std::cout << func([](){ return 21; }) << std::endl;
return 0;
}
这对我来说看起来完全正确。 callback 对象将在 func 函数的整个执行过程中存在,不应为 wrapper 的构造函数制作临时副本。
确实,GCC 4.9.0 在启用所有警告的情况下编译良好。
但是,GCC 4.8.2 编译器给了我以下警告:
$ g++ -std=c++11 -W main.cpp
main.cpp: In constructor ‘func(const callback_func&)::wrapper::wrapper(const callback_func&)’:
main.cpp:12:48: warning: a temporary bound to ‘func(const callback_func&)::wrapper::w_cb’ only persists until the constructor exits [-Wextra]
wrapper(const callback_func& cb) : w_cb {cb} { }
^
这是误报还是我误解了对象的生命周期?
这是我测试的确切编译器版本:
$ g++ --version
g++ (GCC) 4.8.2
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ g++ --version
g++ (GCC) 4.9.0 20140604 (prerelease)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
【问题讨论】:
-
关闭优化会给我一个段错误。 Valgrind 指出问题出在
func(std::function<int ()> const&)::wrapper::call()附近。 -
使用
w_cb {cb}会导致我违反分段。使用w_cb(cb)不会遇到同样的问题。在 g++ 4.8.3 中测试。 -
我可以使用 GCC 4.8.2 重现 Valgrind 错误。 (不是段错误,很难,程序输出 42 并按预期成功退出。) GCC 4.9.0 生成的可执行文件是 Valgrind-clean。这些观察结果不会随着优化级别的不同而改变。
-
我很震惊听到它在某些系统上失败了。 FWIW,在 ideone 的默认设置下工作正常(GCC 4.8.1,
{cb})。
标签: c++ c++11 g++ object-lifetime