C++ 是否有一个GCC选项来警告写“this field”而不是“this->”;字段`?

C++ 是否有一个GCC选项来警告写“this field”而不是“this->”;字段`?,c++,gcc,gcc-warning,C++,Gcc,Gcc Warning,下面的代码(包含一个恶意bug)在没有任何警告的情况下使用GCC编译。但是,当然,它并没有像开发人员(我)期望的那样工作 #包括 结构A { 布尔b; 空集(boolbuj){this->b=b\uj} bool get()const{return this-b;}//错误在这里:'-'而不是'->' }; int main() { A A; a、 设置(真); std::coutNo,this-b正在指针this上执行指针算术,尽管b是bool类型(b隐式转换为int) (有趣的是,您可以将t

下面的代码(包含一个恶意bug)在没有任何警告的情况下使用GCC编译。但是,当然,它并没有像开发人员(我)期望的那样工作

#包括
结构A
{
布尔b;
空集(boolbuj){this->b=b\uj}
bool get()const{return this-b;}//错误在这里:'-'而不是'->'
};
int main()
{
A A;
a、 设置(真);

std::coutNo,
this-b
正在指针
this
上执行指针算术,尽管
b
bool
类型(
b
隐式转换为
int

(有趣的是,您可以将
this+b
设置为
b
bool
类型的指针,因为您可以将指针设置为超过标量末尾的指针!因此即使您最喜欢的未定义行为观察者也会允许该指针。)

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


还要注意的是,在您的案例中,使用
this
是多余的:因此,减少这种过度使用是解决问题的一种方法。

不,没有办法得到警告。隐式转换虽然有悖常理,但语言允许

然而,在这个特定的用例中,我们可以做得更好——将bool包装在一个包装类中,该包装类具有显式转换,并且没有定义算术运算

这会在逻辑上被误用时导致编译器错误,如果目标是逻辑正确性,则通常认为这比警告更可取

有趣的是,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
};
struct Bool
{
显式Bool(Bool b):值_u(b){}
显式运算符bool()常量{返回值}
私人:
布尔值;
//仅定义实际需要的运算符

friend std::ostream&operator此特定问题由
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) 然后,cppcheck通过前面提到的
#ifdef
配置缓慢工作

(作为旁注,
local_classes.tcc
中的错误为假阳性,但对于自动工具来说,这很难判断,因为需要注意的是,当宏
\u异常
未设置时,不应输入此站点的
catch
块。)


免责声明:我没有其他使用cppcheck的经验。

我想推荐另一种工具(除了@arne vogel建议的
cppcheck
),提供更好的视觉帮助,而不是警告:

用于自动格式化代码。结果可能如下所示(取决于设置),通过在
operator-
周围添加空格,使bug更加可见:

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

这是正确的C++语句,所以没有编译器会发出警告。你应该使用静态代码分析工具。C++语句。至少在使用显式警告选项时,我认为这充分说明了为什么单元测试有价值。不要使用<代码> -> <代码>。这将完全避免问题。大多数编译器都会产生“正确的C++语句”的警告:我要说,所有警告都来自“正确”。C++语句。如果不是有效的代码,你会得到一个错误。@ Caduchon:这一决定完全是令人讨厌的。你在哪里划线?用“代码”调用私有成员函数>这个< /代码>!花这笔钱并修复。注意,我使用<代码> My<代码>为成员变量,和<代码> Sy< <代码>静力学。回到我的方框;- @ @浴缸。sheba:使用
this->
在编译时保证它是一个成员。使用
m_
s_
并不能阻止局部/全局变量(不幸的是)这样命名。这是原因。但是,当然,重新开始这个决定可能会很有趣。StackOverflow不是讨论这类问题的最佳平台(我认为)。哪一个可能是好的?我怀疑一个足够聪明的编译器可以发出警告,依赖于
bool(this-n)这一事实
总是正确的。例如,clang已经为隐式
bool(此)发出警告
。我看不出这个答案的任何部分与警告问题有什么关系。当然,这是指针运算。这并不意味着无法检测它是否可疑或生成警告。@snb看。我想我在高盛工作时得到了我的
m_
s_
。我还看到了
my
作为成员的前缀,
our
作为静态的前缀。就我个人而言,虽然我不喜欢依靠语法着色来表示成员变量:配置vi来实现这一点相当困难!然后,我还必须重新创建
std::vector
以减少内存?这显然不是一个解决方案。我不想在ll我的代码…我不知道如何用多个其他问题替换一个问题(用自定义类替换bool的旧用法,或者使用不一致的代码库,确保任何新开发人员也知道这一点并使用它等等,并且到处都有样板代码)是一个很好的解决方案。好吧,它实现了OP想要的功能,但我真的希望没有人真的这么做。@RichardHodges:我明确要求编译器发出警告。有几个隐式转换会生成警告,例如,clang中的
-Wundedeed bool conversion
。“不,没有办法得到警告。隐式转换虽然有悖常理,但语言允许。”这是一个非序列。许多(?all)警告是针对语言允许的内容,但可能是错误的。例如
if(a=f())
将为许多编译器产生警告(如果((a=f())
,这将被
压制。我更喜欢假阳性,而不是潜伏性的错误。:-)当然
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
struct A {
  bool b;
  void set(bool b_) { this->b = b_; }
  bool get() const { return this - b; }
};