Home > Mobile >  warning: '*' in boolean context, suggest '&&' instead [-Wint-in-bool-context]?
warning: '*' in boolean context, suggest '&&' instead [-Wint-in-bool-context]?

Time:01-21

i've this code (which is pretty all "float"):

#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));
// ...

why gcc says warning: '' in boolean context, suggest '&&' instead [-Wint-in-bool-context]* for the second "*"?

  • f is float
  • proto is *float
  • i and m are int

CodePudding user response:

After the macro has been substituted, this part

2.0f * f * sincf(2.0f * f * (i - m / 2.0f));

becomes

 2.0f * f * (2.0f * f * (i - m / 2.0f) == 0.0f) ? ...

and according to operator precedence, the multiplication 2.0f * f * condition will be done before checking if the condition is true (with ?). Like so:

(2.0f * f * (2.0f * f * (i - m / 2.0f) == 0.0f)) ? ...

The quick fix:

#define sincf(x) (((x) == 0.0f) ? (1.0f) : (sinf(M_PI * (x)) / (M_PI * (x))))

(x) == 0.0f will rarely be true but since it's only used to avoid division by zero, that's probably fine.

Now, this could easily be rewritten as a function and I suggest doing that. Example:

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;
}

One could also cast x to double if T is an integral type. Here's a C 20 version of that:

#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);
}
  •  Tags:  
  • Related