MISRA C-2012 Expresiones de flujo de control (MISRA C-2012 Regla 14.2)
for( i = 0; i < FLASH; i++ ) { if( name.see[i] == 0xFF ) { name.see[ i ] = faultId | mnemonicType; i = FLASH-1; /* terminate loop */ } }No está permitido modificar el iterador de bucle i dentro del cuerpo del bucle, hacerlo no tiene sentido y es una práctica muy mala. Reemplace el código ofuscado i = FLASH-1; con break; .
Misra C 2004 regla 13.6 (14.2 en la edición de 2012) dice
Las variables numéricas que se utilizan dentro de un ciclo
forpara el conteo de iteraciones no se modificarán en el cuerpo del ciclo.
El código modifica i para terminar el bucle for (como confirma el comentario). Esto es una violación de la regla.
Misra C 2004 regla 14.6 dice:
Para cualquier declaración de iteración, se utilizará como máximo una declaración de
breakpara la terminación del bucle.
Por lo tanto, puede reemplazar el código ofensivo con una declaración de break simple y aún cumplir:
for (i = 0; i < FLASH; i++) { if (name.see[i] == 0xFF) { name.see[i] = faultId | mnemonicType; break; } } Sin embargo, Misra dice que solo puede hacer esto si hay una sola declaración de break en el ciclo. ¿Qué sucede si desea probar 2 casos diferentes, manejarlos de manera diferente y romper el bucle en cada uno de ellos? El uso de 2 declaraciones de break parece una opción obvia, pero para el cumplimiento necesitaría agregar una variable adicional do_break , configurarla en los lugares donde desea interrumpir y probarla solo una vez al final del cuerpo para ejecutar la declaración de break . No es una muy buena práctica en mi humilde opinión...
Tenga en cuenta estos datos sobre los estándares de codificación Misra C:
Misra volvió a numerar las reglas de una edición a la siguiente, un cambio necesario que crea cierta confusión.
Las reglas no están disponibles en código abierto. Esto ayudaría a difundir algunas buenas prácticas, pero podría decirse que evitó algunas cuestionables.
Esto para bucle
for( i = 0; i < FLASH; i++ ) { if( name.see[i] == 0xFF ) { name.see[ i ] = faultId | mnemonicType; i = FLASH-1; /* terminate loop */ } }no está claro para los lectores del código.
Incluso si vas a escribir
for( i = 0; i < FLASH; i++ ) { if( name.see[i] == 0xFF ) { name.see[ i ] = faultId | mnemonicType; break; } }entonces usar la instrucción break no es un buen enfoque. Cada bloque de código debe tener un punto de entrada y un punto de salida.
De hecho lo que necesitas es encontrar un elemento que satisfaga la condición
name.see[i] == 0xFFy si tal elemento existe, cámbielo.
Por lo tanto, es mejor escribir un ciclo while en lugar de un ciclo for de la siguiente manera
i = 0; wjile ( i < FLASH && name.see[i] != 0xFF ) i++ if ( i != FLASH ) name.see[ i ] = faultId | mnemonicType;La ventaja de este enfoque es que el bucle while tal como está se puede formar como el cuerpo de una función que encuentra un elemento en la matriz. Será suficiente solo agregar la declaración de devolución
return i;