是否有 GCC 选项来警告写“this-field”而不是“this->field”?
Is there a GCC option to warn about writing `this-field` instead of `this->field`?
以下代码(包含一个恶性错误)可以在没有任何警告的情况下使用 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) 添加哪个警告以避免此类错字?
相关问题:是否有任何选项可以强制(或警告)使用 this->
访问成员 variables/functions?
不,this - b
正在对指针 this
执行 指针算术 ,尽管 b
是 bool
类型( b
隐式转换为 int
).
(有趣的是,您可以始终将this + b
设置为一个指针,其中b
是一个bool
类型,因为您可以设置一个指向一个标量末尾的指针!所以即使是你最喜欢的 未定义行为 观察者也会允许那个。)
数组边界检查一直是 C++ 程序员的工作。
另请注意,在您的情况下使用 this
是多余的:因此减少这种过度使用是解决问题的一种方法。
不,没有办法得到警告。隐式转换虽然有悖常理,但却是语言所允许的。
但是,在这个特定的用例中,我们可以做得更好 - 通过将 bool 包装在包装器 class 中,该包装器具有显式转换并且没有定义算术运算。
这会在逻辑上被误用时导致编译器错误,如果逻辑正确性是目标,这通常被视为比警告更可取。
有趣的是,c++17 弃用了 bool::operator++
,因为这种算术被视为邪恶的。
示例:
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
};
此特定问题由 cppcheck
检测到:
$ cppcheck --enable=all this-minus-bool.cxx
Checking this-minus-bool.cxx...
[this-minus-bool.cxx:7]: (warning) Suspicious pointer subtraction. Did you intend to write '->'?
(information) Cppcheck cannot find all the include files (use --check-config for details)
这没有给出包含路径。如果我添加 -I /usr/include/c++/4.8/
,问题仍然被检测到:
Checking this-minus-bool.cxx...
[this-minus-bool.cxx]: (information) Too many #ifdef configurations - cppcheck only checks 12 of 45 configurations. Use --force to check all configurations.
[this-minus-bool.cxx:7]: (warning) Suspicious pointer subtraction. Did you intend to write '->'?
[/usr/include/c++/4.8/bits/ostream.tcc:335]: (style) Struct '__ptr_guard' has a constructor with 1 argument that is not explicit.
[/usr/include/c++/4.8/bits/locale_classes.tcc:248]: (error) Deallocating a deallocated pointer: __c
然后 cppcheck 通过上述 #ifdef
配置慢慢工作。
(附带说明,local_classes.tcc
中的错误是误报,但这对于自动化工具来说很难判断,因为它需要知道 catch
块当宏 __EXCEPTIONS
未设置时不应输入此站点。)
免责声明:我没有使用 cppcheck 的其他经验。
我想推荐另一个工具(@arne-vogel 提出的 cppcheck
除外),提供更好的视觉辅助而不是要求的警告:
使用clang-format自动格式化您的代码。结果可能看起来像这样(取决于设置),通过在 operator-
:
周围添加的空格使错误更明显
struct A {
bool b;
void set(bool b_) { this->b = b_; }
bool get() const { return this - b; }
};
以下代码(包含一个恶性错误)可以在没有任何警告的情况下使用 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) 添加哪个警告以避免此类错字?
相关问题:是否有任何选项可以强制(或警告)使用 this->
访问成员 variables/functions?
不,this - b
正在对指针 this
执行 指针算术 ,尽管 b
是 bool
类型( b
隐式转换为 int
).
(有趣的是,您可以始终将this + b
设置为一个指针,其中b
是一个bool
类型,因为您可以设置一个指向一个标量末尾的指针!所以即使是你最喜欢的 未定义行为 观察者也会允许那个。)
数组边界检查一直是 C++ 程序员的工作。
另请注意,在您的情况下使用 this
是多余的:因此减少这种过度使用是解决问题的一种方法。
不,没有办法得到警告。隐式转换虽然有悖常理,但却是语言所允许的。
但是,在这个特定的用例中,我们可以做得更好 - 通过将 bool 包装在包装器 class 中,该包装器具有显式转换并且没有定义算术运算。
这会在逻辑上被误用时导致编译器错误,如果逻辑正确性是目标,这通常被视为比警告更可取。
有趣的是,c++17 弃用了 bool::operator++
,因为这种算术被视为邪恶的。
示例:
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
};
此特定问题由 cppcheck
检测到:
$ cppcheck --enable=all this-minus-bool.cxx Checking this-minus-bool.cxx... [this-minus-bool.cxx:7]: (warning) Suspicious pointer subtraction. Did you intend to write '->'? (information) Cppcheck cannot find all the include files (use --check-config for details)
这没有给出包含路径。如果我添加 -I /usr/include/c++/4.8/
,问题仍然被检测到:
Checking this-minus-bool.cxx... [this-minus-bool.cxx]: (information) Too many #ifdef configurations - cppcheck only checks 12 of 45 configurations. Use --force to check all configurations. [this-minus-bool.cxx:7]: (warning) Suspicious pointer subtraction. Did you intend to write '->'? [/usr/include/c++/4.8/bits/ostream.tcc:335]: (style) Struct '__ptr_guard' has a constructor with 1 argument that is not explicit. [/usr/include/c++/4.8/bits/locale_classes.tcc:248]: (error) Deallocating a deallocated pointer: __c
然后 cppcheck 通过上述 #ifdef
配置慢慢工作。
(附带说明,local_classes.tcc
中的错误是误报,但这对于自动化工具来说很难判断,因为它需要知道 catch
块当宏 __EXCEPTIONS
未设置时不应输入此站点。)
免责声明:我没有使用 cppcheck 的其他经验。
我想推荐另一个工具(@arne-vogel 提出的 cppcheck
除外),提供更好的视觉辅助而不是要求的警告:
使用clang-format自动格式化您的代码。结果可能看起来像这样(取决于设置),通过在 operator-
:
struct A {
bool b;
void set(bool b_) { this->b = b_; }
bool get() const { return this - b; }
};