考虑下面的代码片段。类test
有一个常量成员a
和一个返回a
的成员函数fun
。一个初始化列表用于在构造函数中初始化a
。但是在初始化列表中,一个lambda用于初始化a
,返回值为fun。这会导致clang和gcc在编译和运行时的不同行为,这取决于优化级别。下面列出了代码段和编译和运行时的不同输出。这是gcc和clang的预期行为吗?
#include <iostream>
class test{
public:
const int a;
test(): a([this](){return fun();}()) {}
int fun()
{
return a;
}
};
int main()
{
auto t = test();
std::cout << t.a << '\n';
return 0;
}
编译时间:
一个一个一个一个一个x一个一个二个一个x一个一个三个一个x一个一个x一个四个一个
运行时间:
clang++-5.0 -std=c++17 -Wall -Wextra -Weverything
0
clang++-5.0 -std=c++17 -Wall -Wextra -Weverything -O1
4196112
g++ -std=c++17 -Wall -Wextra -Wpedantic
Non deterministic output.
g++ -std=c++17 -Wall -Wextra -Wpedantic -O1
0
2条答案
按热度按时间jogvjijk1#
我不太明白一个问题,但它似乎像你实际上是问'为什么gcc没有警告你,直到你出现了优化'。
这是众所周知的事情。在复杂情况下检测未定义行为需要编译器端付出相当多的努力,并且通常只有在优化代码时才能完成(因为编译器无论如何都要做很多工作)。只是在处理真实的生活中的编译器时要记住的事情。
xdnvmnnf2#
您有未定义的行为。您在初始化之前使用了
a
的值。如果您希望您的程序有效,请在使用之前初始化您的变量。你的编译器甚至警告你关于你的代码。听听他们。警告是正确的,你的代码是无效的。