MISRA Discussion Forums

Full Version: 11.3: How many 'levels' deep?
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
While I am not entirely sure from the wording in the document, does this rule only concern itself with comparisons "one level deep"? For example, casting "cv1 type *" to "cv2 type *" is prohibited but "cv1a type * cv1b *" to "cv2a type * cv1b *" is allowed? Would this mean casting "cv1a type * cv1b *" to "cv2a type * cv2b *" is then prohibitted? [Presume each 'cv#' combination is unique.] While the text of the last two examples suggests the answer is "Yes", I'd like to double check.
I'm not sure I've understood the "cv" notation that you've used so I'll use a more verbose description in my reply.

For what it's worth, my interpretation of Rule 11.3 is that it's permitted to convert "pointer to Q1 T" into "pointer to Q2 T" where T is some type and Q1 and Q2 are sets, possibly empty, of type qualifiers. T must be the same type in both cases but Q1 and Q2 may be different. This means that it is permitted to "cast away" a const or volatile qualifier according to Rule 11.3. Protection from the undefined behaviour that might arise in such cases it provided by Rule 11.8 instead.

Rule 11.3 does not permit conversion of "pointer to Q1 T1" into "pointer to Q2 T2" where T1 and T2 are different types, regardless of whether Q1 and Q2 are the same sets of qualifiers. So if T1 is "pointer to const int" and T2 is "pointer to int" then the conversion is prohibited by 11.3.

Therefore I think the answer to the question "How many 'levels' deep?" is "one" though I guess it depends on where you start counting.
The short answer is "one".

A cast from "cv1 Type1 *" to "cv2 Type2 *" will only be compliant with this rule if Type1 and Type2 are the same, including their cv-qualifiers. However the cv-qualifiers ( cv1 and cv2 in your example ) at the top level may differ.

[Note: exceptions apply for casts between pointer to objects and pointers to char, signed char or unsigned char.]
Two follow-up questions:
(1) Where does rule 11.3 state or imply that the casts
Quote:including their cv-qualifiers
must match? Isn't the rule about correct alignment and removing qualifiers is prohibited by rule 11.8 while adding qualifiers is allowed (according to example 2 of rule 11.3)?
(2) Could you please add a example for
Quote:However the cv-qualifiers ( cv1 and cv2 in your example ) at the top level may differ.
?
(1) The Amplification states
Quote:"This rule applies to the unqualified types that are pointed to by pointers".

As explained in the previous answer to this question, only the qualifications at the top level of the type are ignored and therefore any lower qualifiers must be considered.
Consider a variation of the example in the document:
Code:
volatile int * const * pcpvi;     // pcpvi is a "pointer" to a const qualified object of type "pointer to volatile int".

The qualified type pointed to by pcpvi is "const pointer to volatile int"
The unqualified type pointed to by pcpvi is "pointer to volatile int"

Rule 11.3 is only concerned with the unqualified type pointed to by the pointer.
Rule 11.8 is only concerned with the removal of the top-level qualifier.

(volatile int * *) pcpvi would violate rule 11.8 since const removed.

(2) The p and q example in the document shows an example of different top level cv.
Code:
const short *p;               // cv is const
       const volatile short *q;      // cv is const volatile
       // The unqualified object type pointed to by both p and q is "short".
      
       q = ( const volatile short * ) p;  // compliant since both types point to the unqualified type of short.
Question for qualified type and unqualified type.

(1)What is unqualified type and qualified type in the following code?
(2)Is this code compliant with rules?

Code:
typedef const struct a{
  int32_t av = 0;
}A;

typedef const struct b{
  int32_t bv = 0;
  int32_t bv2 = 0;
}B;

void func(A *a)
{
・・・
}

int32_t main(){
A aa;
B bb;
func((*A)&bb);
}
According to ISO/IEC 9899:2011 chapter 6.2.5(type),each unqualified type has a qualified type
corresponding to a combination of qualifiers such as const.
Therefore, it can be interpreted that const qualified unqualified type becomes qualified type.

In this code, the structure is const qualified, so it may be a comparison between qualified types.
If that is correct, this is the compliance code.
There is a cast from
&bb: pointer to a const qualified object of type "struct b"
to
A*: pointer to a const qualified object of type "struct a"

The two pointers do not point to the same type as one points to "const struct b" and the other to "const struct a". Therefore it is a violation of rule 11.3.