如何强制GCC警告类函数的使用
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 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
文件时,我没有警告。但是在复数上使用运算符==
仍然是危险的,就像在双数上使用运算符==
一样(这是选项-Wfloat-equal
存在的原因)。然后,我的问题是:
如果使用复数上的运算符==
,是否可能出现GCC警告(由-Wfloat-equal
激活)我想警告的不是操作员的存在,而是用法。
注意:我将对称运算符定义为类成员,但如果bool operator == (Complex const&,Complex const&)
可以简化我的预期行为,我愿意让它调用类函数bool equals(...) const
注意:由于兼容性原因,我不使用C++11
这似乎有效(在gcc4.8.5上运行):
__attribute__((warning ("your message")))
bool operator == (Complex const& z) const;
当然,您需要确保违规语句没有得到优化。。
实际上,您需要手动(通过一些定义)禁用/启用它。。。我不知道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 !=
留给读者练习。
小更新:如果您希望允许不带Exactly
但带有警告的operator ==
,则需要添加另一个具有Massimiliano Janes提到的属性的重载operator ==(Complex const& a, Complex const& b)
。不过似乎没有必要。
演示
- 如何通过派生类函数更改基类中的向量
- 库函数需要一个 std::function<void(void)>,如何传入类函数?
- 在类函数中初始化外部作用域变量
- c++ 在非类函数中使用类变量
- SDL_PollEvent() 无法捕获类函数内部SDL_QUIT?
- 从类成员函数到类 C 函数指针的转换
- 如何在模板类函数中分配结构值?
- 有没有办法将重载的类函数绑定到函数对象?
- 启动类函数作为失去引用的线程
- C++调用使用重写函数的父类函数
- 将值传递到另一个类函数在打印时为零
- 计算对类函数的所有调用次数
- 由于签名差异,调用了错误的子类函数
- 使用宏调用类函数
- 虚拟基类函数中派生类的大小
- 从多个模板化基类派生时出现"隐藏重载的虚函数"警告
- 模板类/函数中的交叉前向声明
- 在C++中使用非静态类函数的函数
- 无法访问基类函数 C++
- 如何强制GCC警告类函数的使用