Is there a GCC option to warn against spelling `this-field` instead of` this-> field`?

This following code (containing a flawed error) compiles with GCC without warning. But, of course, the developer (s) are not working properly.

#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; } 

What warning can I add for the compiler (GCC 4.8) to avoid this type of typo?

Related question: is it possible to force (or prevent) access to member variables / functions using this-> ?

+61
c ++ gcc gcc-warning
Sep 20 '17 at 10:10
source share
4 answers

This particular problem was discovered by 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)

It was without a path. If I add -I /usr/include/c++/4.8/ , the problem will still be detected:

 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.tcchaps35]: (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

and then cppcheck runs slowly through the above #ifdef configurations.

(As a side note, the error in local_classes.tcc is a false position, but it is very difficult to say for an automated tool, since you need to know that the catch on this site should not be if the __EXCEPTIONS macro __EXCEPTIONS not installed.)

Disclaimer: I have no other experience with cppcheck.

+71
Sep 20 '17 at 11:19 on
source share

No, this - b does pointer arithmetic on the this pointer, even though b is of type bool ( b implicitly converted to int ).

(Interestingly, you can always set this + b to a pointer, where b is the type bool , since you can set the pointer to one after the end of the scalar! So even your favorite undefined spotter behavior would allow this.)

Checking the boundaries of an array has always been a task for a C ++ programmer.

Note that in your cases, using this is redundant: therefore, limiting this excessive use is one way to fix the problem.

+32
Sep 20 '17 at 10:22
source share

I would like to suggest another tool (other than cppcheck suggested by @ arne-vogel), providing better visual support instead of the warning requested:

Use clang-format to automatically format your code. The result may look like this (depending on the settings), making the error more noticeable with spaces added around operator- :

 struct A { bool b; void set(bool b_) { this->b = b_; } bool get() const { return this - b; } }; 
+13
Sep 20 '17 at 19:01
source share

No, there is no way to get a warning. Implicit conversions, although perverse, are allowed by language.

However, in this specific use case, we can do better - by wrapping the bool in a wrapper class that has explicit conversions and arithmetic operations are not defined.

This leads to a compiler error in logical misuse, which is generally considered preferable to warn if the goal is logical correctness.

It is interesting to note that C ++ 17 condemns bool::operator++ , since this arithmetic is considered evil.

Example:

 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 }; 
-one
Sep 20 '17 at 11:01 on
source share



All Articles