对于除文字零之外的所有比较,我可以获得 -Wfloat-equal 的行为吗?

问题描述 投票:0回答:3

我想在我的构建选项中启用 -Wfloat-equal (这是一个 GCC 标志,当通过 == 或 != 运算符比较两个浮点指针数字时会发出警告)。然而,在我使用的库的几个头文件以及我自己的代码的很大一部分中,我经常想使用

if (x)
if (x != 0)
或它们的变体来分支为 float 或 double 的非零值。

因为在这些情况下,我绝对确定该值恰好为零 - 检查的值是显式零初始化的结果,

calloc
等 - 我看不出使用这种比较的缺点,而不是更多对我的
near(x, 0)
函数的调用昂贵且可读性较差。

是否有某种方法可以为所有其他类型的浮点相等比较获得

-Wfloat-equal
的效果,但允许这些不带标记地通过?库头文件中有足够多的实例,它们可能会严重污染我的警告输出。

gcc compiler-warnings
3个回答
2
投票

从你问的问题来看,这个警告似乎是完全恰当的。如果您与精确的零进行比较来测试数据是否仍然具有来自

calloc
的初始零值(从纯 C 的角度来看,这实际上是不正确的,但适用于任何符合 IEEE 754 的实现),您可能会从以下位置得到误报:非零值已四舍五入为零。换句话说,听起来您的代码不正确。


2
投票

这非常可怕,但这避免了警告:

#include <functional>

template <class T>
inline bool is_zero(T v)
{
    return std::equal_to<T>()(v, 0);
}

GCC 不会报告系统标头的警告,这会导致相等测试发生在系统标头内。


0
投票

可以使用

std::fpclassify
函数来检查值是否为零(正数或负数)。

例如:

#include <iostream>
#include <cmath>
#include <cstdlib>

bool is_zero (float x)
{
    return std::fpclassify (x) == FP_ZERO;
}

int main (int, char **)
{
    float a {-0.f};
    float b {+1.f};

    std::cout << is_zero (a) << std::endl;
    std::cout << is_zero (b) << std::endl;

    return EXIT_SUCCESS;
}

构建:

g++ main.cpp -o main -std=c++17 -Wall -Wextra -Wfloat-equal -Wfloat-conversion -Wdouble-promotion

运行:

1
0
© www.soinside.com 2019 - 2024. All rights reserved.