为什么在比较双精度容器时没有来自 -Wfloat-equal 的警告?

Why is there no warning from -Wfloat-equal when comparing containers of doubles?

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

示例代码(也在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;
}

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

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

引自documentation

-Wsystem-headers

Print warning messages for constructs found in system header files. Warnings from system headers are normally suppressed, on the assumption that they usually do not indicate real problems and would only make the compiler output harder to read. Using this command-line option tells GCC to emit warnings from system headers as if they occurred in user code...

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

Clang貌似采用了同样的做法,见https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-in-system-headers and https://clang.llvm.org/docs/UsersManual.html#options-to-control-error-and-warning-messages.

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