警告:布尔上下文中的“*”,建议使用“&&”代替 [-Wint-in-bool-context]?

mar*_*zzz 0 c++ gcc warnings

我有这个代码(几乎都是“浮动”):

#define sincf(x) (x == 0.0f) ? (1.0f) : (sinf(M_PI * x) / (M_PI * x))
// ...
for (int i = 0; i < num_taps; i++)
    proto[i] = 2.0f * f * sincf(2.0f * f * (i - m / 2.0f));
// ...
Run Code Online (Sandbox Code Playgroud)

为什么 gcc 说警告:' ' 在布尔上下文中,建议使用 '&&' 而不是 [-Wint-in-bool-context]* 作为第二个“*”?

  • f 是浮点数
  • 原型是 *float
  • i 和 m 是整数

Ted*_*gmo 6

宏替换后,这部分

2.0f * f * sincf(2.0f * f * (i - m / 2.0f));
Run Code Online (Sandbox Code Playgroud)

变成

 2.0f * f * (2.0f * f * (i - m / 2.0f) == 0.0f) ? ...
Run Code Online (Sandbox Code Playgroud)

根据运算符优先级,2.0f * f * condition在检查条件是否为true(with ?) 之前先进行乘法。就像这样:

(2.0f * f * (2.0f * f * (i - m / 2.0f) == 0.0f)) ? ...
Run Code Online (Sandbox Code Playgroud)

快速修复:

#define sincf(x) (((x) == 0.0f) ? (1.0f) : (sinf(M_PI * (x)) / (M_PI * (x))))
Run Code Online (Sandbox Code Playgroud)

(x) == 0.0f很少会出现这种情况true,但由于它仅用于避免被零除,所以这可能没问题。

现在,这可以很容易地重写为函数,我建议这样做。例子:

template<class T>
T sinc(T x) {
    if(x == T{}) return {1}; // avoid division by zero
    auto pix = static_cast<T>(M_PI) * x;
    return std::sin(pix) / pix;
}
Run Code Online (Sandbox Code Playgroud)

如果是整型,也可以转换x为整型。这是它的 C++20 版本:doubleT

#include <concepts> // std::integral
#include <numbers>  // std::numbers::pi_v

template<class T>
T sinc(T x) {
    if(x == T{}) return 1; // avoid division by zero
    // C++20 added some constants to the standard library:
    auto pix = std::numbers::pi_v<T> * x;
    return std::sin(pix) / pix;
}

double sinc(std::integral auto x) {
    return sinc<double>(x);
}
Run Code Online (Sandbox Code Playgroud)