Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

221
Views
MISRA exige un único punto de salida para una función para una función de "tabla de búsqueda"

Misra estándar exige un único punto de salida para una función, pero tengo el siguiente código de "conversión"

 typedef enum { CASE_A, CASE_B, CASE_C } my_enum_t; int my_conv_funct(my_enum_t value) { switch(value) { case CASE_A: return 0; case CASE_B: return 1; case CASE_C: return 2; default: break; } log_error("ERROR!!!!!"); assert(1==0); }

¿Es esto válido? ¿Necesito convertirlo en una sola función de retorno? ¿Y cuál es la mejor manera de manejar el caso predeterminado?

esto crea un código inalcanzable en teoría (el error es advertir en caso de que uno agregue un valor en la enumeración y no agregue un caso correspondiente)

¿Este es un sistema integrado por cierto que esas afirmaciones crean problemas?

gracias

EDITADO:

el caso predeterminado nunca debe llamarse si no hay errores (por ejemplo, un programador agrega otro valor en la enumeración y no agrega un caso correspondiente

otra opción sería eliminar el valor predeterminado, pero eso viola otra regla misra

 typedef enum { CASE_A, CASE_B, CASE_C } my_enum_t; int my_conv_funct(my_enum_t value) { switch(value) { case CASE_A: return 0; case CASE_B: return 1; case CASE_C: return 2; } //should never reach this line assert(1==0); }

Esto generará una advertencia si compilo y no especifico todos los casos en la enumeración (creo)

over 4 years ago · Santiago Trujillo
3 answers
Answer question

0

Muy simple:

 int my_conv_funct(my_enum_t value) { int result = -1; switch(value) { case CASE_A: result = 0; break; case CASE_B: result = 1; break; case CASE_C: result = 2; break; default: break; } if(result == -1) { log_error("ERROR!!!!!"); assert(1==0); } return result; }
over 4 years ago · Santiago Trujillo Report

0

¿Es esto válido?

No cumple con la regla MISRA que describiste.

¿Necesito convertirlo en una sola función de retorno?

Para cumplir con la regla MISRA, sí.

¿Y cuál es la mejor manera de manejar el caso predeterminado?

No podemos juzgar qué es lo "mejor" para sus circunstancias y uso particulares.

¿Este es un sistema integrado por cierto que esas afirmaciones crean problemas?

La idea de una aserción es que le ayude a encontrar errores de programación durante el desarrollo, pero (en principio) se deshabilita a través de las opciones de compilación en el código que está destinado a usarse en producción. Si se sigue ese modelo, es probable que la aserción en sí misma no cree un problema, pero el hecho de que la función no devuelva un valor en el caso predeterminado (si las aserciones están deshabilitadas) sí lo hace. Si el programa debe terminar en caso de que se ejerza el caso predeterminado, entonces debe llamar a abort() , o alguna otra función que tenga ese efecto. De lo contrario, debería devolver un valor razonable en el caso predeterminado.

Probablemente escribiría la función más así:

 int my_conv_funct(my_enum_t value) { switch(value) { case CASE_A: case CASE_B: case CASE_C: break; default: log_error("ERROR!!!!!"); assert(0); break; } return value; }

Ahora solo hay un punto de salida de la función, y si regresa, entonces devuelve su argumento (implícitamente convertido a tipo int ).

over 4 years ago · Santiago Trujillo Report

0

En primer lugar, compruebe esta respuesta: mejores prácticas para calcular el valor de retorno de la función . La regla MISRA-C es consultiva y recomiendo hacer una desviación permanente contra ella. Personalmente lo reemplazo con una regla como:

"Se deben evitar múltiples declaraciones de retorno en una función a menos que hagan que el código sea más legible/mantenible".

La justificación para evitar regresar desde múltiples lugares dentro del código anidado y complejo es sólida, pero mucho menos en funciones limpias y legibles.

Sin embargo, en su caso específico, tal vez habría reescrito la función de esta manera (compatible con MISRA sin ignorar la regla):

 uint32_t my_conv_funct (my_enum_t value) { uint32_t result; switch(value) { case CASE_A: result = 0; break; case CASE_B: result = 1; break; case CASE_C: result = 2; break; default: { // error handling here } } return result; }

Alternativamente (desviándose de la regla):

 uint32_t my_conv_funct (my_enum_t value) { static const uint32_t lut[] = { CASE_A, CASE_B, CASE_C }; for(size_t i=0; i<sizeof lut/sizeof *lut; i++) { if(lut[i] == value) { return i; } } /* error handling */ return some_error_code; }

Esto suponiendo que la cantidad de elementos no es grande, en cuyo caso una búsqueda binaria podría ser más ineficiente.

Esto, a su vez, suponiendo que las constantes de enumeración no corresponden a 0, 1 y 2, en cuyo caso toda la función no tiene sentido.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!