跨函数禁用clang警告

3
在 clang 中,可以像这里描述的那样忽略警告。
在我的例子中,如果代码直接包含在编译指示中(参见(1)),则可以正常工作。但是,在函数(3)中出现问题的代码不适用于(2)。只有当我将该函数用编译指示括起来(注释掉)时,才会忽略警告。如果该函数在头文件中,则还可以用编译指示括起#include
一般情况下,我希望为该函数提供警告,但我不想为其所在的整个文件禁用警告。因此,是否有一种方法可以针对每个使用情况禁用警告?
#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;
}

使用-Weverything编译


我认为这实际上是clang中的一个错误。 - Mats Petersson
2个回答

1
你可以通过仅实例化此函数来解决这个问题:
#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

现在,所有其他警告都会出现,所以如果您做了其他“错误”的事情,它仍然会发出警告。
但正如我在评论中所说的那样,这可能被认为是编译器中的一个错误,因此我建议报告并查看clang开发人员的意见。

1
警告是针对使用 == 进行比较而发出的,而不是针对调用而发出的。如果您有两个都调用 compare<float>的函数,并且您以某种方式设法抑制了第一个调用的警告,则在第二个调用中将不会剩下任何警告: compare<float>已经被实例化,并且只有在实例化期间才检测到任何警告。

您应该找到可以附加到调用 compare<float>的警告。默认参数在调用站点有效地得到评估,快速测试表明它很好用:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接