Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Rule 11.6. A cast between pointer to void and an arithmetic type. Value of the rule.
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 *:

  1. 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.
  2. 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.
  3. 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?
1. The working-group agrees that the first paragraph of the rationale needs amending. It should refer to implementation behaviour (C99 J.3.7(1)), not alignment issues or undefined behaviour.

2. The working-group agrees the rationale does not apply to a conversion to intptr_t/uintptr_t. The group will review casts to intptr_t/uintptr_t in a later release. It is permissible to convert between void* and intptr_t/uintptr_t if you write a deviation to the rule.

3. Thank you for your comment.

The Advisory/Required categories for the rule 11.X rules are planned to be reviewed as part of future work on the MISRA C guidelines.
Posted by and on behalf of the MISRA C Working Group
Thank you. Your official answer will help justifying the deviation.

Forum Jump:

Users browsing this thread: 1 Guest(s)