Estoy trabajando en un proyecto en el que estamos aplicando MISRA 2004.
En la mayoría de las violaciones obtuve el motivo, pero no entiendo una:
Está en la instrucción if con && y || operaciones.
Ejemplo:
uint8 getValue() { // Some algorithm, simplified with return 1 uint8 someValue = 1u; return someValue; } int main(int argc, char *argv[]) { uint8 currentState = 0u; uint8 var_a = getValue(); uint8 var_b = getValue(); uint8 var_c = getValue(); uint8 var_d = getValue(); const uint8 const_a = 1u; const uint8 const_b = 2u; const uint8 const_c1 = 3u; const uint8 const_c2 = 30u; const uint8 const_d = 4u; if ((var_a == const_a) && (var_b == const_b) && ((var_c == const_c1) || (var_c == const_c2)) && (var_d == const_d)) { currentState = 1; } else { currentState = 2; } }Esto me da el doble de la violación MISRA a la regla 12.5 expresión no primaria utilizada con el operador lógico. Ambos están en línea con el IF-Statement
No veo ningún problema con esta declaración if, a pesar de que es un poco larga.
¿Alguien sabe qué está mal aquí y cómo resolver esa violación?
Editar: ajusté un poco el ejemplo. También noté que solo obtengo un error si simplifico la declaración if a:
if ((var_a == const_a) && ((var_c == const_c1) || (var_c == const_c2)) && (var_d == const_d))Y no hay violación si se cambia a:
if ((var_a == const_a) && ((var_c == const_c1) || (var_c == const_c2)))Esto parece ser un falso positivo de su analizador estático. Su código es compatible.
El fundamento de MISRA C:2004 12.5 (y las reglas equivalentes en la versión de 2012) es evitar situaciones en las que la precedencia de operadores no sea obvia. En general, MISRA insiste en que las subexpresiones que involucran operadores binarios ("expresiones complejas") siempre deben tener paréntesis.
En el caso de los booleanos && y || operadores específicamente, la regla 12.5 permite encadenar múltiples de ellos en la misma expresión, pero no mezclar && y || en la misma expresión sin paréntesis, ya que tienen distinta precedencia.
¿Habías escrito && (var_c == const_c1) || (var_c == const_c2) && entonces el código sería no conforme. Sin embargo, no lo hizo, y también puso paréntesis alrededor de las subexpresiones internas.