如何强制 GCC 警告使用 class 函数?
How to force GCC to warn about usage of a class function?
使用 GCC 4.8.*,当激活警告 -Wfloat-equal
时,编译器会警告浮点数之间的严格比较,如下例所示:
double x = 3.14159;
double y = 1.11111;
if(x == y) // <-- this induces a warning
{ /* ... */ }
现在,假设我想要一个包含双变量并定义相等运算符的 class:
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);
}
这正是我所期望的。当然,当我编译 class 时它会引发警告。为了避免它(因为我理解警告,感谢编译器,但我想这样做,我不想继续看到警告),我通过这种方式通知编译器:
#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
文件时没有收到警告。但是在复数上 使用 运算符 ==
仍然很危险,就像在双数上使用运算符 ==
一样危险(这是存在的原因选项 -Wfloat-equal
)。那么,我的问题:
是否可以在复数上使用运算符==
时发出GCC警告(由-Wfloat-equal
激活)?不存在我想警告的操作员,但用法。
注意:我将对称运算符定义为 class 成员,但我愿意让 class 函数 bool equals(...) const
由 bool operator == (Complex const&,Complex const&)
如果它可以简化我的预期行为。
注意:出于兼容性原因,我不使用 C++11。
这似乎有效 (live on gcc4.8.5):
__attribute__((warning ("your message")))
bool operator == (Complex const& z) const;
当然,您需要确保有问题的语句不会被优化掉..
实际上,您需要 dis/enable 手动(通过一些定义)...我不知道 gcc 是否允许检查是否已启用警告。
使用 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));
并添加一个"maker"函数,这样就不用重复类型名了,比如Complex
:
template<typename T>
Exactly<T> exactly(T const& value)
{
return Exactly<T>(value);
}
operator !=
作为练习留给 reader。
小更新:如果你想允许operator ==
没有Exactly
,但有警告,那么你需要添加另一个重载operator ==(Complex const& a, Complex const& b)
具有 Massimiliano Janes 提到的属性。不过好像没必要。
使用 GCC 4.8.*,当激活警告 -Wfloat-equal
时,编译器会警告浮点数之间的严格比较,如下例所示:
double x = 3.14159;
double y = 1.11111;
if(x == y) // <-- this induces a warning
{ /* ... */ }
现在,假设我想要一个包含双变量并定义相等运算符的 class:
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);
}
这正是我所期望的。当然,当我编译 class 时它会引发警告。为了避免它(因为我理解警告,感谢编译器,但我想这样做,我不想继续看到警告),我通过这种方式通知编译器:
#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
文件时没有收到警告。但是在复数上 使用 运算符 ==
仍然很危险,就像在双数上使用运算符 ==
一样危险(这是存在的原因选项 -Wfloat-equal
)。那么,我的问题:
是否可以在复数上使用运算符==
时发出GCC警告(由-Wfloat-equal
激活)?不存在我想警告的操作员,但用法。
注意:我将对称运算符定义为 class 成员,但我愿意让 class 函数 bool equals(...) const
由 bool operator == (Complex const&,Complex const&)
如果它可以简化我的预期行为。
注意:出于兼容性原因,我不使用 C++11。
这似乎有效 (live on gcc4.8.5):
__attribute__((warning ("your message")))
bool operator == (Complex const& z) const;
当然,您需要确保有问题的语句不会被优化掉..
实际上,您需要 dis/enable 手动(通过一些定义)...我不知道 gcc 是否允许检查是否已启用警告。
使用 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));
并添加一个"maker"函数,这样就不用重复类型名了,比如Complex
:
template<typename T>
Exactly<T> exactly(T const& value)
{
return Exactly<T>(value);
}
operator !=
作为练习留给 reader。
小更新:如果你想允许operator ==
没有Exactly
,但有警告,那么你需要添加另一个重载operator ==(Complex const& a, Complex const& b)
具有 Massimiliano Janes 提到的属性。不过好像没必要。