为什么在比较双精度数容器时 -Wfloat-equal 没有发出警告?

oli*_*ver 6 c++ floating-point warnings clang gcc-warning

如果我将编译器选项-Wfloat-equal与 GCC 或 Clang 一起使用,浮点/双精度值的相等比较会导致警告。但是,当比较float 或 double 值的容器(如std::vectorstd::tuple)时,不会引发此类警告。

示例代码(也在https://godbolt.org/z/YP8v8hTs3):

#include <tuple>
#include <vector>
#include <assert.h>

int main() {
    double d = 1.2;

    std::tuple<double, double> t_d{1.2, 3.14};
    std::tuple<double, double> t_d_2{1.2, 3.14};

    std::vector<double> v_d{1.2, 3.14};
    std::vector<double> v_d_2{1.2, 3.14};

    // this causes a warning, like "warning: comparing floating-point with '==' or '!=' is unsafe [-Wfloat-equal]":
    assert(d == 1.2);
    // but why no warning from -Wfloat-equal here?
    assert(t_d == t_d_2);
    // no warning here either:
    assert(v_d == v_d_2);

    // all of these cause warnings as expected:
    assert(std::get<0>(t_d) == 1.2);
    assert(std::get<0>(t_d) == std::get<0>(t_d_2));
    assert(v_d[0] == 1.2);
    assert(v_d[0] == v_d_2[0]);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

为什么这些容器比较中省略了警告?更重要的是,我该怎么做才能真正收到这些警告?

Dan*_*ica 5

默认情况下, GCC不报告系统标头的警告。可以通过添加编译器标志来获得所需的行为-Wsystem-header

文档中的引用:

-Wsystem-headers

打印系统头文件中发现的构造的警告消息。来自系统头的警告通常会被抑制,假设它们通常不指示真正的问题,只会使编译器输出更难以阅读。使用此命令行选项告诉 GCC 从系统标头发出警告,就像它们发生在用户代码中一样......

现场演示: https: //godbolt.org/z/s6rExszj6

Clang似乎采用了相同的方法,请参阅https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-in-system-headershttps://clang.llvm.org/docs/UsersManual.html#控制错误和警告消息的选项

现场演示:https://godbolt.org/z/n9xY8rcM8