06-09-2018, 12:18 PM
Good day. To analyze a finding supported by this rule in a project I'd like to understand the intention of the rule. Specifically, in the context of C99 I fail to find an appropriate rationale to disallow converting between intptr_t/uintptr_t and void *:
In addition to failing to find an appropriate rationale for disallowing conversions between intptr_t/uintptr_t and void * I see positive value in favoring these over conversions between intptr_t/uintptr_t and object pointers. One advantage is the above mentioned alignment, but also that holding addresses as pointers to void prevents accidental accesses to the object. The more specific case of mine is when pointers to objects are produced by de-serialization (for which uintptr_t is the most preferred type) and the objects are used nearly nowhere in the program but in copy operations via memcpy. Improving compliance with MISRA C:2012 requires to convert the value into an object pointer first, which creates the risk of accidental dereferencing in the code, and only then into a pointer to void to pass the value to memcpy. This allows to trade a deviation from the required rule 11.6 for the deviation of the advisory rule 11.4. But at the same time the code then seems to become less safe.
So were the conversions between intptr_t/uintptr_t and void * disallowed unintentionally or do I just miss a safer way to handle the above described situations than to deviate from 11.6?
Quote:Conversion of an integer into a pointer to void may result in a pointer that is not correctly aligned, resulting in undefined behaviour.
Would you, please, explain how this rationale is compatible with the following statement in the C90/C99 standards:
C99. 6.2.5 Types. §27 Wrote:A pointer to void shall have the same representation and alignment requirements as a pointer to a character type.
As character pointers contain addresses of individual bytes, they cannot be unaligned. Hence pointers to void cannot be unaligned too, right?
Moreover, for the cases, in which the alignment problem indeed may occur, the restriction you define (rule 11.4) is, in contrast to 11.6, only advisory.
Quote:Conversion of a pointer to void into an integer may produce a value that cannot be represented in the chosen integer type resulting in undefined behaviour.
This rationale does not apply to intptr_t/uintptr_t.
Quote:Conversion between any non-integer arithmetic type and pointer to void is undefined.
This rationale looks like it would deserve a separate rule, as the limitations of these conversions for integers and non-integer arithmetic types are very different.
In addition to failing to find an appropriate rationale for disallowing conversions between intptr_t/uintptr_t and void * I see positive value in favoring these over conversions between intptr_t/uintptr_t and object pointers. One advantage is the above mentioned alignment, but also that holding addresses as pointers to void prevents accidental accesses to the object. The more specific case of mine is when pointers to objects are produced by de-serialization (for which uintptr_t is the most preferred type) and the objects are used nearly nowhere in the program but in copy operations via memcpy. Improving compliance with MISRA C:2012 requires to convert the value into an object pointer first, which creates the risk of accidental dereferencing in the code, and only then into a pointer to void to pass the value to memcpy. This allows to trade a deviation from the required rule 11.6 for the deviation of the advisory rule 11.4. But at the same time the code then seems to become less safe.
So were the conversions between intptr_t/uintptr_t and void * disallowed unintentionally or do I just miss a safer way to handle the above described situations than to deviate from 11.6?
<t></t>