当使用 Clang 8.0.0 编译以下(简化的)代码时,使用 -O1
优化级别(或更高),Valgrind 检测到 Conditional jump or move depends on uninitialised value(s)
结果二进制文件中的错误。没有打印警告,即使是 -Wall -pedantic
启用参数。添加-fsanitize=undefined
只是让问题消失,但没有报告任何有用的信息。而且它很可能不是误报(来自 Valgrind),因为这个简化版本源自真实的代码库,它导致了一个明显的错误。
使用 GCC 9.1.1 编译时,没有 UB。
#include <algorithm>
#include <iostream>
class X {
public:
int a, b;
X(int a) : a(a), b(0) {}
bool h() {
std::initializer_list<bool> bs({a == 0, a != 0 || b == 0});
return std::any_of(bs.begin(), bs.end(), [](bool t) { return t; });
}
};
void f(X g) {
std::cout << "";
}
int main(int argc, const char **) {
X i(argc);
f(i);
if (i.h())
std::cout << "";
}
当然,std::initializer_list<bool> bs({a == 0, a != 0 || b == 0});
line 有点奇怪,外括号是不必要的。但是根据cppinsights.io ,这只是添加了一个复制构造函数调用,所以应该没问题吧? ( See the same code in Compiler Explorer. )
另请注意,代码中所有看似无用的细节都是触发问题所必需的。
因此,即使在大多数情况下,这个问题的答案是“否”:这是 Clang 中的一个错误吗?还是我们只是遗漏了现代 C++ 的古怪之处? p>
最佳答案
我认为我们遇到了一个问题,该问题已在 LLVM 错误跟踪器中报告过三次:
- https://bugs.llvm.org/show_bug.cgi?id=22861
- https://bugs.llvm.org/show_bug.cgi?id=40562
- https://bugs.llvm.org/show_bug.cgi?id=42561
并且很可能与这个 SO 问题相关(甚至可能相同):
LLVM 人员目前对此的立场是:“……我们应该对此发出警告。”好吧,是的,我同意。
Oh, C++... :)
关于c++ - initializer_list 中的未初始化值(编译器错误?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57226951/