visual tutorial studio para descargar configurar compilar compilador code c++ gcc gcc-warning

c++ - tutorial - ¿Existe una opción de GCC para advertir sobre escribir `this-field` en lugar de` this-> field`?



netbeans c++ descargar (4)

El siguiente código (que contiene un error vicioso) se compila con GCC sin previo aviso. Pero, por supuesto, no funciona como lo esperaba el desarrollador (yo).

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

¿Qué advertencia puedo agregar para el compilador (GCC 4.8) para evitar este tipo de error tipográfico?

Pregunta vinculada: ¿Hay alguna opción para forzar (o advertir) el acceso a las variables / funciones miembro con this-> ?


Este problema en particular es detectado por 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)

Esto fue sin ruta de inclusión dada. Si agrego -I /usr/include/c++/4.8/ , el problema aún se detecta:

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

y luego cppcheck funciona lentamente a través de las configuraciones #ifdef mencionadas #ifdef .

(Como nota al margen, el error en local_classes.tcc es un falso positivo, pero es muy difícil saberlo para una herramienta automatizada, ya que sería necesario tener en cuenta que el bloque catch en este sitio no debe ingresarse cuando la macro __EXCEPTIONS está desarmado)

Descargo de responsabilidad: no tengo otra experiencia con cppcheck.


Me gustaría sugerir otra herramienta (además de cppcheck propuesta por @ arne-vogel), que ofrece una mejor ayuda visual en lugar de la advertencia solicitada:

Use clang-format automáticamente su código. El resultado podría verse así (dependiendo de la configuración), haciendo que el error sea más visible por los espacios agregados alrededor del operator- :

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


No, this - b realiza aritmética de puntero en el puntero, a pesar de que b es un tipo bool ( b se convierte implícitamente en int ).

(Curiosamente, siempre puede establecer this + b en un puntero donde b es un tipo bool , ¡ya que puede establecer un puntero en uno más allá del final de un escalar! Así que incluso su observador de comportamiento indefinido favorito lo permitiría).

La comprobación de límites de matriz siempre ha sido el trabajo de un programador de C ++.

Tenga en cuenta también que en sus casos el uso de this es superfluo: por lo tanto, reducir este uso excesivo es una forma de hacer que el problema desaparezca.


No, no hay forma de recibir una advertencia. Las conversiones implícitas, aunque perversas, están permitidas por el lenguaje.

Sin embargo, en este caso de uso específico podemos hacerlo mejor: envolviendo el bool en una clase de contenedor que tiene conversiones explícitas y no hay operaciones aritméticas definidas.

Esto da como resultado un error del compilador cuando se usa incorrectamente lógicamente, lo que normalmente se considera preferible a una advertencia si el objetivo es la corrección lógica.

Es interesante notar que c ++ 17 desprecia bool::operator++ ya que esta aritmética se considera malvada.

ejemplo:

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