En C y C ++, es muy fácil escribir el siguiente código con un error grave.
char responseChar = getchar();
int confirmExit = 'y' == tolower(responseChar);
if (confirmExit = 1)
{
exit(0);
}
El error es que la declaración if debería haber sido:
if (confirmExit == 1)
Según lo codificado, saldrá cada vez, porque se confirmExit
produce la asignación de la variable, y luego confirmExit
se utiliza como resultado de la expresión.
¿Hay buenas maneras de prevenir este tipo de error?
c++
coding-standards
DesarrolladorDon
fuente
fuente
if (confirmExit)
.a = b
oa == b
dentro de un condicional.Respuestas:
La mejor técnica es aumentar el nivel de advertencia de su compilador. Luego le advertirá sobre la posible asignación en el condicional if.
Asegúrese de compilar su código con cero advertencias (lo que debería estar haciendo de todos modos). Si desea ser pedante, configure su compilador para tratar las advertencias como errores.
El uso de condicionales Yoda (poner la constante en el lado izquierdo) fue otra técnica que fue popular hace aproximadamente una década. Pero hacen que el código sea más difícil de leer (y, por lo tanto, se mantienen debido a la forma poco natural en que leen (a menos que sea Yoda)) y no brindan un beneficio mayor que el aumento del nivel de advertencia (que también tiene beneficios adicionales de más advertencias).
Las advertencias son realmente errores lógicos en el código y deben corregirse.
fuente
if (0 == ret)
horror.a == b
!0==a && 0==b || 1==a && 1==b || 2==a && 2==b || ...
(repita para todos los valores posibles). No olvide el...|| 22==a && 22==b || 23==a && 24==b || 25==a && 25==b ||
error obligatorio ... o los programadores de mantenimiento no se divertirán.Siempre puedes hacer algo radical como probar tu software. Ni siquiera me refiero a las pruebas unitarias automatizadas, solo las pruebas que cada desarrollador experimentado hace por costumbre al ejecutar su nuevo código dos veces, una vez que confirma la salida y otra vez que no. Esa es la razón por la cual la mayoría de los programadores lo consideran un problema.
fuente
rc=MethodThatRarelyFails(); if(rc = SUCCESS){
más de una vez, especialmente si el método falla solo en condiciones difíciles de evaluar.Una forma tradicional de evitar el uso incorrecto de las asignaciones dentro de la expresión es colocar la constante a la izquierda y la variable a la derecha.
El compilador informará un error para la asignación ilegal a una constante similar a la siguiente.
La condición if revisada sería:
Como se muestra en los comentarios a continuación, muchos lo consideran un método inapropiado.
fuente
Estoy de acuerdo con que todos digan "advertencias del compilador" pero quiero agregar otra técnica: Revisiones de código. Si tiene una política de revisar todo el código que se compromete, preferiblemente antes de que se confirme, es probable que este tipo de cosas se detecte durante la revisión.
fuente
Primero, elevar sus niveles de advertencia nunca está de más.
Si no desea que su condicional pruebe el resultado de una asignación dentro de la declaración if en sí, entonces haber trabajado con muchos programadores de C y C ++ a lo largo de los años, y nunca haber escuchado que comparar la constante primero
if(1 == val)
era algo malo, usted podría intentar esa construcción.Si el líder de su proyecto aprueba que haga esto, no se preocupe por lo que piensen los demás. La verdadera prueba es si usted u otra persona pueden darle sentido a su código dentro de meses y años.
Sin embargo, si su intención era probar el resultado de una asignación, el uso de advertencias más altas podría [probablemente haber] capturado la asignación a una constante.
fuente
if ( auto myPtr = dynamic_cast<some_ptr>(testPtr) ) {
que evita mantener unnullptr
alcance inútil si falla el lanzamiento, lo que presumiblemente es la razón por la que C ++ tiene esta capacidad limitada para asignar dentro de un condicional. Por lo demás, sí, una definición debería tener su propia línea, yo diría: mucho más fácil de ver de un vistazo y menos propensa a diversos descuidos.Tarde a la fiesta como siempre, pero el análisis de código estático es la clave aquí
La mayoría de los IDE ahora proporcionan SCA más allá de la verificación sintáctica del compilador, y hay otras herramientas disponibles, incluidas las que implementan las directrices MISRA (*) y / o CERT-C.
Declaración: formo parte del grupo de trabajo MISRA C, pero estoy publicando a título personal. También soy independiente de cualquier proveedor de herramientas
fuente
Solo use la asignación de la mano izquierda, las advertencias del compilador pueden ayudar, pero debe asegurarse de obtener el nivel correcto; de lo contrario, se verá inundado de advertencias sin sentido o no se le dirán las que desea ver.
fuente