Lambda:应该逐引用捕获const引用,从而产生未定义的行为
lambda: should capturing const reference by reference yield undefined behaviour?
我刚刚在我的代码中发现了一个严重的错误,因为我通过引用捕获了对字符串的const引用。当lambda运行时,原始字符串对象已经消失很久了,引用的值是空的,而目的是它将包含原始字符串的值,因此出现了错误。
让我困惑的是,这并没有在运行时调用崩溃:毕竟,这不应该是未定义的行为,因为有一个悬空引用?此外,当在调试器下查看id时,它甚至看起来不像垃圾,而只是像一个正确构造的空字符串。
下面是测试用例;这只是打印一个空行:
typedef std::vector< std::function< void() > > functions;
void AddFunction( const std::string& id, functions& funs )
{
funs.push_back( [&id] ()
{
//the type of id is const std::string&, but there
//is no object to reference. UB?
std::cout << id << std::endl;
} );
}
int main()
{
functions funs;
AddFunction( "id", funs );
funs[ 0 ]();
}
未定义的行为意味着没有要求应该发生什么。没有要求它应该崩溃。无论悬空引用指向的内存是什么,都没有理由不包含看起来像空字符串的东西,而且string
的析构函数使内存处于这种状态是合理的。
通过引用捕获任何东西意味着您必须注意它的存活时间足够长。如果你不这样做,程序可能会正常工作,但它可能会打电话给达美乐,点一份双层意大利辣香肠。
(正如dascandy指出的那样)这个问题与const和引用语法几乎没有关系,更简单地说,这是放弃了在引用时确保通过引用传递的所有内容存在的责任。函数调用中的字面量对于该调用来说是严格临时的,并在返回时消失,因此我们访问的是临时的——编译器经常检测到的一个缺陷——只是在这种情况下没有。
typedef std::vector<std::function<void()> > functions;
void AddFunction(const std::string& id, functions& funs) {
funs.push_back([&id] ()
{
//the type of id is const std::string&, but there
//is no object to reference. UB?
std::cout <<"id="<< id << std::endl;
});
}
int emain() {
functions funs;
std::string ida("idA");
// let idB be done by the tenporary literal below
std::string idc("idC");
AddFunction(ida, funs);
AddFunction("idB", funs);
AddFunction(idc, funs);
funs[0]();
//funs[1](); // uncomment this for (possibly) bizarre results
funs[2]();
std::cout<<"emain exit"<<std::endl;
return 0;
}
int main(int argc, char* argv[]){
int iret = emain();
return 0;
}
相关文章:
- 编译C++时未定义的引用
- 如何修复此错误:未定义对"距离(浮点数,浮点数,浮点数,浮点数,浮点数)"的引用
- 我的项目不会像"undefined reference to `grpc::g_core_codegen_interface'"那样使用未定义的引用错误进行编译
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 未定义的引用在哪里
- 编译时的 CImg 库返回对"__imp_SetDIBitsToDevice"的未定义引用
- 对Py_Initialize()的未定义引用
- 使用mysql c++连接器的未定义引用
- 未定义的引用 .. 使用 OpenCV 编译 C++ 代码时,从命令行
- 对 Scalar ::Scalar() 的未定义引用
- 已定义函数时出现 G++ "未定义的引用"错误
- 链接 cmake 时出现未定义的引用错误
- 对复制 CTOR 和 CTOR 的未定义引用
- 错误:未定义对'oboe::AudioStreamBuilder::openStream(oboe::AudioStream**)'的引用
- 右值引用未定义的行为
- 对"vtable for DigitalClock"的未定义引用 - 未定义对"DigitalClock::staticMetaObject"的引用 - Qt
- 函数类型到函数类型的引用:未定义的引用
- avcodec_alloc_context引用未定义,但ffmpeg链接顺序正确
- 从c++调用Fortran子程序,链接时引用未定义
- 枚举引用未定义,但位于包含的头文件中