有没有海湾合作委员会的选项来警告写`this-field`而不是`this-> field`?

这下面的代码(包含一个恶性bug)编译与GCC没有任何警告。 但是,当然,这并不像开发人员(我)预期的那样工作。

#include <iostream> struct A { bool b; void set(bool b_) { this->b = b_; } bool get() const { return this-b; } // The bug is here: '-' instead of '->' }; int main() { A a; a.set(true); std::cout << a.get() << std::endl; // Print 1 a.set(false); std::cout << a.get() << std::endl; // Print 1 too... return 0; } 

我可以为编译器(GCC 4.8)添加哪个警告来避免这种types的错字?

链接的问题:是否有任何选项强迫(或警告)访问成员variables/函数与this->

这个特定的问题被cppcheck检测到:

 $ cppcheck --enable = all this-minus-bool.cxx 
检查this-minus-bool.cxx ...
 [this-minus-bool.cxx:7] :(警告)可疑的指针减法。 你打算写' - >'吗?
 (信息)Cppcheck找不到所有包含文件(使用--check-config查看详细信息)

这是没有包括path给出。 如果我添加-I /usr/include/c++/4.8/ ,问题仍然被检测到:

检查this-minus-bool.cxx ...
 [this-minus-bool.cxx] :(信息)#ifdefconfiguration过多 -  cppcheck只检查45个configuration中的12个。 使用--force检查所有configuration。
 [this-minus-bool.cxx:7] :(警告)可疑的指针减法。 你打算写' - >'吗?
 [/usr/include/c++/4.8/bits/ostream.tcc:335]:(style)Struct'__ptr_guard'有一个带有1个参数的构造函数,它不是显式的。
 [/usr/include/c++/4.8/bits/locale_classes.tcc:248] :(错误)取消分配一个释放的指针:__c

然后cppcheck慢慢地通过前面提到的#ifdefconfiguration。

(请注意, local_classes.tcc中的错误是错误的,但是这很难说是一个自动化的工具,因为它需要知道当macros中的catch块不应该被input__EXCEPTIONS未设置。)

免责声明:我没有其他经验与cppcheck。

不, this - b正在对指针 this - b进行指针运算 ,尽pipeb是一个booltypes( b隐式转换为int )。

(有趣的是,你总是可以设置this + b为一个指针,其中b是一个booltypes,因为你可以设置一个指针到一个标量的末尾,所以即使你最喜欢的未定义的行为监视器也会允许这个指针。

数组边界检查一直是C ++程序员的工作。

还要注意,在你的情况下,使用this是多余的:所以减less这种过度使用是使问题消失的一种方法。

我想build议另一个工具(除了@ arne-vogel提出的cppcheck之外),给予更好的视觉帮助,而不是要求的警告:

使用clang格式自动格式化您的代码。 结果可能看起来像这样(取决于设置),通过在operator-周围添加的空格使bug更加可见:

 struct A { bool b; void set(bool b_) { this->b = b_; } bool get() const { return this - b; } }; 

不,没有办法得到警告。 隐含的转换,虽然是不正当的,但这是语言所允许的。

但是,在这个特定的用例中,我们可以做得更好 – 通过将bool包装在一个包含显式转换并且没有定义算术操作的包装类中。

这会导致编译器在逻辑错误时出错,如果逻辑正确是目标,这通常被认为比警告更好。

有趣的是,c ++ 17弃用了bool::operator++因为这个algorithm被认为是邪恶的。

例:

 struct Bool { explicit Bool(bool b) : value_(b) {} explicit operator bool() const { return value_; } private: bool value_; // define only the operators you actually want friend std::ostream& operator<<(std::ostream& os, const Bool& b) { return os << b; } }; struct X { bool foo() { // compilation failure - no arithemetic operators defined. // return bool(this-b); // explicit conversion is fine return bool(b); } Bool b { true }; // explicit initialisation fine };