MISRA Rule 11.3 compliance?

johncdp wrote on Thursday, February 12, 2015:

I’m trying to evaluate the comparability of FreeRTOS with the MISRA-C 2012 guidelines to see if it would fit a project we’re working on.
I know that you’ve made a great effort to conform to the guidelines and document exceptions as required, and we really do appreciate that!

I did however encounter many instances where rule 11.3 is not met and the exception is not documented. I wanted to know if this is perhaps a misunderstanding of mine (and our MISRA-checking tool) or if this is indeed the case.

The rule states that “A cast shall not be performed between a pointer to object type and a pointer to a different object type”. The rule also states that the only exception to this is casting to a pointer to char, signed char or unsigned char.

There are, however, many lines such as:
Queue_t * const pxQueue = ( Queue_t * ) xQueue;
in the FreeRTOS code.
The problem here is the xQueue pointer (QueueHandle_t, a void * pointer) being converted to a Queue_t pointer which points to a structure.

I’d like to hear your opinion on this and please do let me know if I got this wrong.
Thank you very much in advance!

rtel wrote on Saturday, February 14, 2015:

Sorry for the delay - all posts made two days ago went into moderation. That should not happen.

I think MISRA 2004 was used.

Be careful with your use of MISRA. It is a guide. If you try and comply with it exactly then your code will be worst because it will have to be bent to the rules, resulting in more code, and less understandable code.

For example:

The problem here is the xQueue pointer (QueueHandle_t, a void * pointer) being converted to a Queue_t pointer which points to a structure.

…that is normal data hiding, considered to be best practice in software engineering, especially when providing a library for others to use. If the structure was past around directly it would be exposed for all users to see, resulting in users tinkering with the contents, inadvertently creating bugs (because they can’t be expected to understand the consequences of their tinkering) and more effort and expense on maintenance (if they use the API then new updated code can be dropped in with no changes, if they tinker with the structure because the structures contents have been exposed, then changes in the structures will break their code).

MISRA compliance does definitely NOT mean that all the rules are blindly followed, compliance means rules that are not followed are deviated in a justifiable way.

MISRA is brilliant for code reviews because it highlights areas that need special scrutiny. If a rule is broken you can examine the code, and get a senior/experience engineer to justify why the code should be left as it is - or if that [real rather than lazy] justification cannot be made, the code is changed.

When I worked in the safety critical field people asked for 100% compliance, which showed they were inexperienced, and would either end up with bent code, or eventually start using the standard as a quality guide (as it intended) rather than legislation.


richard_damon wrote on Saturday, February 14, 2015:

The actual fix to be MISRA compliant would be to have QueueHandle_t be a Queue_t* but only provide a forward definition for Queue_t. As I remember, the issue here is that, at least at one point, some of the compilers that were being supported didn’t allow for such a forward declaration of a structure. Since a compiler that doesn’t support this is at least 25 years out of date, it might make sense to check if this work around is still needed, or if the handle types can be upgraded to pointers to the right structure types that are forward declared.

In one sense this MISRA failure is really an issue as the use of void* pointers in this way does open the door for some nasty bugs of having the wrong type object passed into functions.

rtel wrote on Saturday, February 14, 2015:

Yes - having to build with so many compilers is always challenging!

Another issue was actually with debuggers. A ‘typesafe’ version of
FreeRTOS was created (there was a long thread about it some time back),
but the changes had to be backed out because it broke some kernel aware
debuggers. Something to do with bugs in the elf parsers.


richard_damon wrote on Saturday, February 14, 2015:

Have you ever looked at the possibility of making the choice between a void * and a struct xxx_t* be a compile time decision based on a symbol defined in the port header to force the fall back in the few cases it doesn’t work, but still letting the other systems gain the advantage of type safety.

Since C defines that void* pointers can be impicitly converted to other pointer types (so malloc and such work) you don’t really need the cast brought up in the initial post (unless the broken compilers are broken in this aspect, somewhat unlikely as that would force a cast on every use of malloc).