有没有海湾合作委员会的选项来警告写`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慢慢地通过前面提到的#ifdef
configuration。
(请注意, local_classes.tcc
中的错误是错误的,但是这很难说是一个自动化的工具,因为它需要知道当macros中的catch
块不应该被input__EXCEPTIONS
未设置。)
免责声明:我没有其他经验与cppcheck。
不, this - b
正在对指针 this - b
进行指针运算 ,尽pipeb
是一个bool
types( b
隐式转换为int
)。
(有趣的是,你总是可以设置this + b
为一个指针,其中b
是一个bool
types,因为你可以设置一个指针到一个标量的末尾,所以即使你最喜欢的未定义的行为监视器也会允许这个指针。
数组边界检查一直是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 };