La razón detrás de Misra 2012 no permite el lanzamiento entre diferentes punteros.

Actualmente estoy trabajando en un proyecto que requiere que el código sea compatible con Misra 2012. A lo largo del proyecto, tenemos muchas advertencias erróneas requeridas que nos dicen que no podemos convertir el puntero a un tipo a un puntero a otro tipo. Cosas tan simples como void *memcpy(void *to, const void *from, size_t n) producen dos advertencias de Misra Required, ya que tanto desde y hacia la necesidad deben escribirse a void * y const void * respectivamente. La conversión de void * a un puntero a cualquier otro tipo también muestra una advertencia de Misra.

Mi pregunta es ¿cómo espera Misra que malloc y todo lo demás funcionen sin que se emitan advertencias? ¿Incluso convertir un búfer void * en un búfer uint8_t * para analizar byte por byte y rellenar todos los elementos de una estructura de estructura generará numerosas advertencias?

En lugar de estas advertencias, ¿no podría simplemente mostrar el uso de una nota o información solicitándonos que volvamos a revisar el empaque, la alineación y cualquier otra cosa que pueda salir mal?

Me gustaría volver a lo que pidió el OP y aclarar algunas cosas. En primer lugar, no hay ningún problema en llamar a void * memcpy (void * a, const void * from, size_t n), ya que la conversión de un puntero a objeto a un puntero void no viola ninguna directriz MISRA-C: 2012. En otras palabras, cualquier herramienta que produzca violaciones para eso es simplemente defectuosa.

En segundo lugar, antes de llegar a una conclusión, es importante leer lo que dice la Regla 11.5, la directriz relevante de MISRA-C: 2012, que es:

   Regla 11.5
   No se debe realizar una conversión de puntero a vacío en
   puntero a objeto

   Asesor de Categoría
   Análisis decidible, unidad de traducción única
   Se aplica a C90, C99

   Razón fundamental
   Puede resultar la conversión de un puntero para anular en un puntero a objeto
   en un puntero que no está alineado correctamente, lo que resulta en indefinido
   comportamiento.  Debe evitarse donde sea posible pero puede ser necesario,
   por ejemplo cuando se trata de funciones de asignación de memoria.  Si
   se utiliza la conversión de un puntero a objeto en un puntero a vacío,
   se debe tener cuidado para asegurar que cualquier puntero producido no
   dar lugar al comportamiento indefinido discutido bajo la Regla 11.3.

Observaciones:

  1. es una regla de asesoría (es decir, ni requerida ni obligatoria), por lo que puede desviarse, y MISRA definió el proceso de desviación correcto;
  2. convertir un puntero en objeto a un puntero a vacío está bien: es al revés lo que es problemático;
  3. la justificación menciona explícitamente las funciones de asignación de memoria (y, sí, un progtwig que utiliza asignación dinámica de memoria puede ser compatible con MISRA-C: 2012);
  4. la justificación proporciona orientación sobre qué hacer cuando se convierten punteros en objetos a punteros para anular, perfectamente en línea con lo que al OP le gustaría tener (“la información nos pide que revisemos el empaque, la alineación y cualquier otra cosa que pueda salir mal”).

Esto no responde a su pregunta, que es sobre los fundamentos. Más bien, señala que no debería estar en esta situación en primer lugar.

Escribir “misra malloc” en tu motor de búsqueda favorito nos lleva a:

http://www.misra.org.uk/forum/viewtopic.php?t=260

que pregunta:

Según la regla, no se supone que utilicemos funciones como malloc (), free (), calloc (), etc. Pero malloc () es un requisito muy común. La mayoría de las aplicaciones de sistemas integrados utilizan sus propios gestores de memoria de nivel de aplicación para agilizar la asignación y la desasignación. ¿Tiene alguna sugerencia para solucionar este problema (si no podemos usar malloc, de alguna otra manera)?

Y la respuesta es:

Se nos ha preguntado acerca de las soluciones y soluciones alternativas para varias cosas que están prohibidas tanto en MISRA C1 como en MISRA C2, como el uso de malloc, calloc, etc. para la asignación de memoria dinámica. Ni MISRA ni ningún miembro del Grupo de trabajo MISRA C brindarán orientación o aprobación a ninguna desviación o “solución alternativa”.


Usted tiene el requisito de que el código cumpla con cierta norma. Estás utilizando mecanismos que no cumplen con esa norma. Averigüe una forma sólida y basada en principios para cumplir, o proponga una política clara sobre cómo tratar el incumplimiento deliberado.

Mencionas memcpy, por ejemplo. No es compatible. Así que dé un paso atrás y pregunte “suponga que no tuve ninguna implementación de memcpy. ¿Cómo escribiría mi propio memcpy que cumpliera con las normas ?” Estás usando memcpy para resolver un problema; Resuelve el problema sin él.

Ahora haz lo mismo para malloc. Hubo un día en que no existía malloc, y alguien tenía que escribirlo sin malloc. Tienes un problema que es solucionado por malloc. Si no tuvieras malloc, ¿cómo lo resolverías? Nada en Malloc es mágico; puedes escribir el tuyo que haga un mejor trabajo que malloc, donde “mejor” quiero decir “cumple con tus requisitos”.

MISRA-C: 2012 es en realidad un tanto relajado cuando se trata de conversiones de puntero. La mayoría de las reglas son correctas, se preocupan de obligarte a seguir el estándar de C, no invocar un comportamiento indefinido o hacer cosas universalmente malas como desechar los calificadores const de un puntero. No deberías tener ninguna objeción contra nada de eso.

La única regla controvertida es 11.5:

No se debe realizar una conversión desde un puntero para anular en un puntero a objeto.

Creo que esto es lo que te causa dolor de cabeza. El fundamento es las preocupaciones de alineación y las conversiones entre tipos de punteros incompatibles, lo que llevaría a un comportamiento indefinido.

Esa regla, de hecho, prohíbe indirectamente el uso de muchas funciones básicas de la biblioteca como memcpy . Mi recomendación personal a MISRA con respecto a esta regla durante la revisión de 2012 fue:

(Totalmente en desacuerdo) “Hay demasiados casos de progtwigción genérica de C cuando se requieren lanzamientos de punteros de vacío. Esta regla no es práctica y hará más daño que bien. En cambio, haga una regla que prohíba el peligro específico que la regla trata de proteger. , es decir, “puntero a x, conversión a vacío *, conversión a puntero a y”.

Pero ellos no escucharon, y ahí lo tienen: una regla inútil que obliga a cada herramienta a arrojar una avalancha de falsos positivos. Lo que significa que cada usuario de MISRA debe ignorar esta regla. Es un aviso para que pueda ignorarlo sin levantar ningún procedimiento de desviación. Solo bloquéalo en tu analizador de estática y sigue adelante.

El comité de MISRA aún no se ha dado cuenta de que los falsos positivos son un peligro para la seguridad en sí mismo, ya que podría hacer que las personas comiencen a escribir de nuevo el código perfecto y, por lo tanto, introducir errores.

¿Cómo espera Misra Malloc?

MISRA espera que no uses malloc en absoluto, está explícitamente prohibido por la directiva 4.12, por razones muy sólidas. Pero ese es otro tema.