He escrito una función simple para inicializar los valores de la estructura usando memset() . Estos son el código que he escrito en lenguaje C.
miarchivo.h
typedef struct{ bool flag; bool check; int val_1; int val_2; } MY_STRUCT;miarchivo.c
static MY_STRUCT mystruct; void Test() { memset(&mystruct, 0, sizeof(MY_STRUCT)); }Cuando ejecuto MISRA, recibo este tipo de error
The return value of non-void function 'memset' shall be usedHe intentado arreglar esta advertencia usando el siguiente método
(void)memset(&mystruct, 0, sizeof(MY_STRUCT));Pero desafortunadamente, estoy recibiendo 2 nuevas advertencias.
Cast between types that are not both pointers or not pointers object of pointer type 'void*' cast to unrelated type 'void' ¿Alguien sugiere cómo solucionar esta advertencia al usar la función memset() ? También explique para evitar este tipo de advertencias en el futuro.
Debe comprender la lógica detrás de las reglas si va a trabajar con MISRA-C.
De hecho, el primer problema debería resolverse convirtiendo el resultado en (void) . El motivo de esta regla es hacer cumplir la verificación de errores de los valores devueltos por las funciones, lo que no se aplica en este caso, ya que la API ciertamente extraña de memset simplemente devuelve el primer parámetro.
El resto de las advertencias que recibe parecen ser falsos positivos de su herramienta. Es compatible convertir explícitamente el valor devuelto de cualquier función a (void) , consulte MISRA C:2012 17.7.
No se requiere una solución alternativa para el cumplimiento de MISRA, aunque si solo desea silenciar la herramienta, esto también sería compatible con MISRA y sería equivalente a memset:
mystruct = (struct MY_STRUCT){ 0u };El valor de retorno de la función memset es un puntero void* , que es una copia del primer parámetro pasado ( dest ). En su caso, esa es la dirección de una variable real , por lo que no puede ser NULL ; por lo tanto, comparar el valor devuelto con NULL probablemente evitaría la advertencia de MISRA (pero esa prueba realmente nunca debería fallar):
if (!memset(&mystruct, 0, sizeof(MY_STRUCT))) { (void)fputs("I'm sorry, but an impossible error has occurred!\n", stderr); }El código citado:
static MY_STRUCT mystruct; void Test() { memset(&mystruct, 0, sizeof(MY_STRUCT)); }Es una violación de MISRA C:2012 Regla requerida 17.7 que establece, sin ambigüedades, que se utilizará el valor devuelto por una función que tiene un tipo de devolución no nulo .
memset() devuelve un void* y, por lo tanto, para cumplir con la Regla 17.7 debe usarse o, como sugiere la Regla, convertir en void .
Mientras que en el caso específico de memset() se podría argumentar que el valor de retorno no tiene sentido , el idioma es el idioma y la Regla MISRA no tiene una excepción.
Agregar un lanzamiento a (void) no debería ser una sobrecarga... pero si está especialmente preocupado, siempre puede desviarse de la regla.