【发布时间】:2026-01-19 23:30:01
【问题描述】:
考虑这段代码,它是从here 稍微修改的:
#include <iostream>
void foo() {
int i;
static auto f = [&i]() { std::cout << &i << "\n";};
f();
}
int main() {
foo();
foo();
}
lambda f 仅在第一次调用时初始化,在第二次调用期间,捕获的变量不再存在,lambda 持有一个悬空引用,但只打印其地址。 gcc 没有明显问题,输出看起来还可以:
0x7ffc25301ddc
0x7ffc25301ddc
获取悬空引用的地址是未定义的行为,还是可以?
对于一个非常相似的例子 gcc ( -Wall -Werror -pedantic -O3) 会产生一个警告:
#include <iostream>
auto bar() {
int i;
return [&i]() {std::cout << &i << "\n"; };
}
int main() {
bar()();
}
警告:
source>:5:14: error: address of stack memory associated with local variable 'i' returned [-Werror,-Wreturn-stack-address]
return [&i]() {std::cout << &i << "\n"; };
^
<source>:5:14: note: captured by reference here
return [&i]() {std::cout << &i << "\n"; };
当然,gcc 编译第一个示例并产生预期(?)输出而第二个示例发出警告这一事实并不意味着什么。在标准中我可以在哪里找到使用悬空引用的地址是否可以?
PS:我想答案在 [basic.life] 中的某个地方,虽然我浏览了好几次,但我很难看到什么适用以及它试图告诉我什么。
【问题讨论】:
-
FWIW,在我看来,像您在此处所做的那样,在静态 lambda 中捕获本地变量至少不会产生警告,这是一种疏忽。
-
timsong-cpp.github.io/cppwp/n4868/basic.stc.general#4 对引用会发生什么保持沉默,所以我会说它未指定
-
@500-InternalServerError 是的,我也认为这是一个疏忽。实际上,我试图让优化器产生一些意想不到的输出,但那个警告是我能得到的“最好的”。
标签: c++ reference language-lawyer undefined-behavior