Violation of Rule 11.4 or Rule 11.5?

6.11 Pointer Type Conversions

Moderators: misra-c, david ward

Post Reply
zaffanella
Posts: 5
Joined: Tue Jun 10, 2008 7:12 pm
Company: University of Parma (Italy)

Violation of Rule 11.4 or Rule 11.5?

Post by zaffanella » Fri Mar 06, 2009 9:36 am

In Section 6.11 of the MISRA-C:2004 document, after the specification of Rule 11.5, the following example is reported:

Code: Select all

/* ... snip ... */
const uint16_t * *  ppci;     /* pointer to pointer to const */
uint16_t * *  ppi;
/* ... snip ... */
ppi = (uint16_t  * *)ppci;           /* Not compliant               */
In my understanding, this is not really a violation of the required Rule 11.5; rather, it is a violation of the advisory Rule 11.4, since the pointed-to types
(namely,

Code: Select all

const uint16_t *
and

Code: Select all

uint16_t *
)
are two different pointer (hence, object) types; in particular, they are unqualified types.

This is quite the same as saying that

Code: Select all

struct S { const char* s; };
struct T { char* s; };
struct S* ps;
struct T* pt = (struct T*) ps;
is a violation of 11.4 rather than 11.5.

Is my interpretation correct?
Or is it the case that Rule 11.5 has to be interpreted recursively,
so that in the two examples above we would have violations for both 11.4 and 11.5?

Thanks,
Enea.

Lundin
Posts: 70
Joined: Mon Dec 10, 2007 1:57 pm

Re: Violation of Rule 11.4 or Rule 11.5?

Post by Lundin » Fri Mar 06, 2009 2:58 pm

But in your example you are removing the const qualifier with that typecast. Instead of a pointer to const-pointer, you get a pointer-to-pointer.
C will allow you to continue your snippet like this:

uint16_t data;
**ppi = data;


I don't think you can regard the declaration of pointer-to-pointers as several recursive type declarations. The const has to be taken into account at every cast.
Because, in order to grant all C programmers insanity, the following ISO-complicant cases exist:

Type** name1;
const Type** name2;
Type* const * name3;
Type** const name4;
const Type** const name5;
Type* const * const name6;
const Type* const * const name7;

zaffanella
Posts: 5
Joined: Tue Jun 10, 2008 7:12 pm
Company: University of Parma (Italy)

Re: Violation of Rule 11.4 or Rule 11.5?

Post by zaffanella » Fri Mar 06, 2009 10:55 pm

My reading of the C standard is that int* and const int* are two unqualified, different object types.
Hence, if Rule 11.4 is to be taken literally, converting a const int** to a int** is a violation.
Actually, even when converting the other way round, from int** to const int**,
i.e., when adding an inner-level qualifier, we should have a violation of Rule 11.4.

My question is how far should we go when considering Rule 11.5: is this rule meant to overlap with 11.4 or not?

Suppose that the quality control process requires the programmer to raise a formal deviation for each violation of a rule,
no matter if it is a mandatory or an advisory rule.
Consider my second example above, with the cast between different structure types.
Is it enough to raise a formal deviation for Rule 11.4, or should the programmer also raise a formal deviation for Rule 11.5?

Consider the following minor variant:

Code: Select all

struct S { const int* i; };
struct T { float* f; };
struct S* ps;
struct T* pt = (struct T*) ps;
Again, is this a violation of just 11.4, or is it also violating 11.5?

Trickier examples can be proposed where the two structure types have differently qualified fields
that are not perfectly overlapping. For instance,

Code: Select all

struct S { const int i; const int j; };
struct T { int i; char a; const char b; char c; const char d; };
struct S* ps;
struct T* pt = (struct T*) ps;
Thanks,
Enea.

misra-c
Posts: 566
Joined: Thu Jan 05, 2006 1:11 pm

Re: Violation of Rule 11.4 or Rule 11.5?

Post by misra-c » Tue Apr 07, 2009 8:28 pm

The final statement in the example code for 11.5 is misleading.
It is, in fact, a violation of Rule 11.4.

Code: Select all

uint16_t                 x;
uint16_t * const         cpi = &x;     /* const pointer               */
uint16_t * const       * pcpi;         /* pointer to const pointer    */
const uint16_t *       * ppci;         /* pointer to pointer to const */
uint16_t *             * ppi;
const uint16_t         * pci;          /* pointer to const            */
volatile uint16_t      * pvi;          /* pointer to volatile         */
uint16_t               * pi;
...
pi = cpi;                              /* Compliant - no conversion
                                                   no cast required   */
pi  = (uint16_t *)pci;                 /* Not compliant - Rule 11.5   */
pi  = (uint16_t *)pvi;                 /* Not compliant - Rule 11.5   */
ppi = (uint16_t * *)pcpi;              /* Not compliant - Rule 11.5   */
ppi = (uint16_t * *)ppci;              /* Not compliant - Rule 11.4   */
A pointer which addresses a "pointer to uint16_t" and a pointer which addresses a "pointer to const uint16_t" are pointers which address identically qualified versions of different types. A pointer which addresses a "pointer to uint16_t" and a pointer which addresses a "const pointer to uint16_t" are pointers which address differently qualified versions of identical types.
---
Posted by and on behalf of
the MISRA C Working Group

Post Reply

Return to “6.11 Pointer Type Conversions”