如何强制GCC警告类函数的使用?

时间:2017-11-17 10:18:11

标签: c++ gcc c++03 pragma gcc-warning

使用GCC 4.8。*,当警告-Wfloat-equal被激活时,编译器会警告浮点数之间的严格比较,如下例所示:

double x = 3.14159;
double y = 1.11111;
if(x == y) // <-- this induces a warning
{ /* ... */ }

现在,想象一下我想要一个包含双变量的类并定义相等运算符:

class Complex // (it's only an example)
{
  private:
    double re;
    double im;
  public:
    bool operator == (Complex const& z) const;
};
bool Complex::operator == (Complex const& z) const
{
  return (this->re == z.re) && (this->im == z.im);
}

这完全符合我的期望。当然,在编译课程时它会引发警告。为了避免它(因为我理解警告,感谢编译器,但我想这样做,而且我不想继续看到警告),我通过这种方式通知编译器:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
bool Complex::operator == (Complex const& z) const
{
  return (this->re == z.re) && (this->im == z.im);
}
#pragma GCC diagnostic pop

好的,我在编译Complex.cpp文件时没有收到警告。但是对于复杂数字使用运算符==仍然很危险,例如在双数字上使用运算符==会很危险(&#&# 39;选项-Wfloat-equal)存在的原因。然后,我的问题:

是否可以使用GCC警告(由-Wfloat-equal激活),其中使用了复数上的运算符==它不存在操作员我想警告,但用法。

注意:我将对称运算符定义为类成员,但如果它可以简化我的预期行为,我可以打开bool equals(...) const调用的类函数bool operator == (Complex const&,Complex const&)

注意:出于兼容性原因,我不会使用C ++ 11.

2 个答案:

答案 0 :(得分:2)

这似乎有效(live on gcc4.8.5):

__attribute__((warning ("your message")))
bool operator == (Complex const& z) const;

当然,你需要确保有问题的陈述没有得到优化..

实际上,您需要手动取消/启用它(通过某些定义)...我不知道gcc是否允许检查是否已启用警告。

答案 1 :(得分:0)

如何使用明确表达意图的Exactly包装类型?

template<typename T>
struct Exactly : T
{
    explicit Exactly(T const& value) : T(value) {}
};

class Complex
{
    double re;
    double im;

public:
    Complex(double re, double im) : re(re), im(im) {}

    // Non-members require either friend access or public getters.
    double real() const { return re; }
    double imag() const { return im; }
};

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wfloat-equal"
bool operator == (Complex const& a, Exactly<Complex> const& b)
{
    return (a.real() == b.real()) && (a.imag() == b.imag());
}
// two more overloads for completeness
bool operator == (Exactly<Complex> const& a, Complex const& b)
{
    return (a.real() == b.real()) && (a.imag() == b.imag());
}
bool operator == (Exactly<Complex> const& a, Exactly<Complex> const& b)
{
    return (a.real() == b.real()) && (a.imag() == b.imag());
}
#pragma GCC diagnostic pop

然后,您也可以预定义这样的常量(例如本地或命名空间):

Exactly<Complex> exactlyOne(Complex(1.0, 0.0));

并添加&#34;制造商&#34;功能,以便您不必重复类型名称,如Complex

template<typename T>
Exactly<T> exactly(T const& value)
{
    return Exactly<T>(value);
}

operator !=留给读者练习。

次要更新:如果您想允许operator ==没有Exactly但有警告,那么您需要添加另一个带有属性的重载operator ==(Complex const& a, Complex const& b) Massimiliano Janes提到。似乎没必要。

Demo