Martin
Martin

Reputation: 63

Disable clang warnings across functions

In clang we can ignore warnings as described here.

In my example this works fine if the code is directly enclosed in the pragmas (see (1)). However this doesn't work at (2) because the offending code is inside a function (3). The warning is only ignored if I enclose the function with a pragma (commented out). If the function is inside a header I can also enclose the #include with a pragma.

I generally want warnings for this function but I don't want to disable them for the whole file it is used in. So is there a way to disable the warning on a per-use case?

#include <iostream>

// #pragma clang diagnostic push
// #pragma clang diagnostic ignored "-Wfloat-equal"
template <class T>
bool compare (const T lhs, const T rhs)
{
  return lhs == rhs; // (3)
}
// #pragma clang diagnostic pop

int main ()
{
  const float a = 1.1f, b = 1.1f;

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
  const bool eq1 = a == b; // (1)
#pragma clang diagnostic pop

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
  const bool eq2 = compare (a, b); // (2)
#pragma clang diagnostic pop

  std::cout << eq1 << " " << eq2 << std::endl;

  return 0;
}

Compile with -Weverything

Upvotes: 3

Views: 3265

Answers (2)

user743382
user743382

Reputation:

The warning is emitted for the comparison using ==, not for the call. If you have two functions that both call compare<float>, and you would somehow manage to suppress the warning for the first call, there wouldn't be anything left to warn for in the second call: compare<float> has already been instantiated, and it's only during instantiation that anything is detected to warn about.

You should probably find a warning that can be attached to a call to compare<float>. A default argument effectively gets evaluated at the call site, and a quick test shows that it works well for that:

template <typename T>
bool compare(T a, T b, bool = decltype(a == b)()) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
  return a == b;
#pragma clang diagnostic pop
}

// Gets a warning
void f() { compare(1.0f, 1.0f); }

// Suppress the warning here
void g() { compare(1.0f, 2.0f, false); }

// Gets another warning
void h() { compare(1.0f, 3.0f); }

Upvotes: 1

Mats Petersson
Mats Petersson

Reputation: 129314

You could work around this by instantiating only this function:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wfloat-equal"
template <>
bool compare (const float lhs, const float rhs)
{
  return lhs == rhs;
}
#pragma clang diagnostic pop

Now, all other warnings will appear, so if you do something else "wrong", it will still warn.

But like I said in the comment, it may be considered a bug in the compiler, so I would report it and see what the clang developers say.

Upvotes: 1

Related Questions