for*_*818 8 c++ reference undefined-behavior language-lawyer
考虑这段代码,它是从这里稍微修改的:
#include <iostream>
void foo() {
int i;
static auto f = [&i]() { std::cout << &i << "\n";};
f();
}
int main() {
foo();
foo();
}
Run Code Online (Sandbox Code Playgroud)
lambdaf仅在第一次调用时初始化,在第二次调用期间捕获的变量不再存在,lambda 保留悬空引用,但仅打印其地址。gcc没有明显问题,输出看起来没问题:
0x7ffc25301ddc
0x7ffc25301ddc
Run Code Online (Sandbox Code Playgroud)
获取悬空引用的地址是未定义的行为,还是可以?
对于一个非常相似的示例,gcc ( -Wall -Werror -pedantic -O3) 会生成警告:
#include <iostream>
auto bar() {
int i;
return [&i]() {std::cout << &i << "\n"; };
}
int main() {
bar()();
}
Run Code Online (Sandbox Code Playgroud)
警告:
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"; };
Run Code Online (Sandbox Code Playgroud)
当然,gcc 编译第一个示例并生成预期的(?)输出,同时警告第二个示例这一事实并不意味着什么。在标准中的哪里可以找到使用悬空引用的地址是否可以?
PS:我想答案就在[basic.life]中的某个地方,尽管我浏览了几次,但我很难看出什么适用以及它试图告诉我什么。
是的,这是未定义的行为,因为将&地址运算符应用于引用会检索所引用对象的地址,在您的示例中,该地址不再存在,因为它已超出范围并被销毁。您无法获取不存在的对象的地址。
| 归档时间: |
|
| 查看次数: |
286 次 |
| 最近记录: |