问题
I am currently working on a project which requires the code to be Misra 2012 compliant. Throughout the project we have lots of required misra warnings telling us we cant convert pointer to one type to a pointer to another type. Things as simple as void *memcpy(void *to, const void *from, size_t n)
produce two Misra Required warnings since both to and from need to be type-casted to void* and const void* respectively.
Conversion from void* to a pointer to any other type also gives a Misra warning.
My question is how does Misra expect malloc and everything else to work without any warnings being thrown? Even converting a void* buffer to uint8_t* buffer to parse abuffer byte by byte and fill up all the elements of a structure structure will throw numerous warnings?
Instead of these warnings could it not just show use a note or info asking us to double check packing, alignment and anything else that might go wrong?
回答1:
I would like to go back to what the OP asked and get a few things straight. First of all, there is no problem in calling void *memcpy(void *to, const void *from, size_t n), as a conversion of a pointer to object to a void pointer does not violate any MISRA-C:2012 guideline. In other words, any tool producing violations for that is simply buggy.
Secondly, before coming to any conclusion it is important to read what Rule 11.5, the relevant MISRA-C:2012 guideline, actually says, that is:
Rule 11.5 A conversion should not be performed from pointer to void into pointer to object Category Advisory Analysis Decidable, Single Translation Unit Applies to C90, C99 Rationale Conversion of a pointer to void into a pointer to object may result in a pointer that is not correctly aligned, resulting in undefined behaviour. It should be avoided where possible but may be necessary, for example when dealing with memory allocation functions. If conversion from a pointer to object into a pointer to void is used, care should be taken to ensure that any pointers produced do not give rise to the undefined behaviour discussed under Rule 11.3.
Observations:
- it is an advisory rule (i.e., neither required nor mandatory), so it can be deviated, and MISRA defined the correct deviation process;
- converting a pointer to object to a pointer to void is fine: it is the other way around that is problematic;
- the rationale explicitly mentions memory allocation functions (and, yes, a program that uses dynamic memory allocation can be made compliant to MISRA-C:2012);
- the rationale provides guidance on what to do when converting pointers to objects to pointers to void, perfectly in line with that the OP would like to have ("info asking us to double check packing, alignment and anything else that might go wrong").
回答2:
This does not answer your question, which is about rationales. Rather, it points out that you should not be in this situation in the first place.
Typing "misra malloc" into your favourite search engine leads us to:
http://www.misra.org.uk/forum/viewtopic.php?t=260
which asks:
As per the rule we are not supposed to use functions like malloc(), free(), calloc() etc. But malloc() is a very common requirement. Most of the embedded system applications use their own application level memory managers so as to make the allocation and de-allocation fast. Do you have any suggestions to get around this problem ( if we can't use malloc, any other way )?
And the answer is:
We have been asked about solutions and workarounds for various things that are prohibited in both MISRA C1 and MISRA C2 such as using malloc, calloc, etc. for dynamic memory allocation. Neither MISRA or any member of the MISRA C Working Group will give any guidance or approval to any deviation or "workaround".
You have a requirement that the code comply with a certain standard. You're using mechanisms which don't comply with that standard. Either figure out a principled and robust way to comply, or come up with a clear policy for how to deal with deliberate non-compliance.
You mention memcpy, for example. It's non-compliant. So take a step back and ask "suppose I did not have any implementation of memcpy. How would I write my own memcpy that was compliant?" You're using memcpy to solve a problem; solve the problem without it.
Now do the same for malloc. There was a day when malloc didn't exist, and someone had to write it without malloc. You have a problem that is solved by malloc. If you didn't have malloc, how would you solve it? Nothing in malloc is magical; you can write your own that does a better job than malloc does, where by "better" I mean "complies with your requirements".
回答3:
MISRA-C:2012 is actually somewhat lax when it comes to pointer conversions. Most rules are sound, concerned with forcing you to follow the C standard, not invoking undefined behavior, or do universally bad things like casting away const qualifiers from a pointer. You shouldn't have any objections against any of that.
The only controversial rule is 11.5:
A conversion should not be performed from a pointer to void into a pointer to object.
I think this one is what causes you head ache. The rationale is alignment concerns and conversions between incompatible pointer types, which would lead to undefined behavior.
That rule does indeed indirectly ban the use of many basic library functions like memcpy
. My personal recommendation to MISRA regarding this rule during the 2012 review was:
(Strongly disagree) "There are too many cases of generic C programming when void pointer casts are necessary. This rule isn't practical and will do more harm than good. Instead, make a rule banning the specific danger the rule tries to protect against, namely "pointer-to-x, cast to void*, cast to pointer-to-y"."
But they didn't listen, and there you have it: a useless rule which forces every tool to spew out a flood of false positives. Meaning that every single user of MISRA has to ignore this rule. It is Advisory so you can ignore it without raising any deviation procedure. Just block it in your static analyser and move on.
The MISRA committee has yet to realize that false positives is a safety hazard in itself, since it might lead to people starting to re-write perfectly fine code and thereby introducing bugs.
how does Misra expect malloc
MISRA expects you not to use malloc at all, it is explicitly banned by directive 4.12, for very sound reasons. But that's another topic.
来源:https://stackoverflow.com/questions/35465754/rationale-behind-misra-2012-not-allowing-cast-between-different-pointers