[cfe-dev] A doubt about cvr-qualified array types.

Abramo Bagnara abramo.bagnara at gmail.com
Sun Oct 24 11:03:11 PDT 2010


Il 23/10/2010 20:45, Eli Friedman ha scritto:
> On Sat, Oct 23, 2010 at 10:29 AM, Abramo Bagnara
> <abramo.bagnara at gmail.com> wrote:
>> Il 23/10/2010 19:09, Eli Friedman ha scritto:
>>> On Sat, Oct 23, 2010 at 2:15 AM, Enea Zaffanella <zaffanella at cs.unipr.it> wrote:
>>>> Hello.
>>>>
>>>> We have a doubt regarding qualified array types.
>>>>
>>>> Consider the following program:
>>>> ===============================
>>>> struct S {
>>>>  int a[2];
>>>> };
>>>>
>>>> void foo(void) {
>>>>  const struct S* ps;
>>>>  const int (*b)[2];
>>>>  b = &ps->a;
>>>> }
>>>> ===============================
>>>> as well as its ast dump:
>>>> ===============================
>>>> struct S {
>>>>    int a[2];
>>>> };
>>>> void foo() (CompoundStmt 0x3c48bf8 <arraytype.c:5:16, line:9:1>
>>>>  (DeclStmt 0x3c1be20 <line:6:3, col:21>
>>>>    0x3c1bdd0 "const struct S *ps")
>>>>  (DeclStmt 0x3c1bf60 <line:7:3, col:20>
>>>>    0x3c1bf10 "const int (*b)[2]")
>>>>  (BinaryOperator 0x3c48bc8 <line:8:3, col:12> 'const int (*)[2]' '='
>>>>    (DeclRefExpr 0x3c1bf80 <col:3> 'const int (*)[2]' Var='b' 0x3c1bf10)
>>>>    (UnaryOperator 0x3c48ba0 <col:7, col:12> 'int const (*)[2]' prefix '&'
>>>>      (MemberExpr 0x3c48b30 <col:8, col:12> 'int const[2]' ->a 0x3c1bc10
>>>>        (DeclRefExpr 0x3c1bfb8 <col:8> 'const struct S *' Var='ps'
>>>> 0x3c1bdd0)))))
>>>> ===============================
>>>>
>>>> The dump shows a mismatch between the types of the lhs and the rhs of
>>>> the assignment expression:
>>>>  - the lhs has type    const int (*)[2]
>>>>  - the rhs has type    int const (*)[2]
>>>> that is, in the rhs the const qualifier is applied to the array type,
>>>> rather than to the array element type. The two types are anyway detected
>>>> as being equivalent as witnessed by the absence of an implicit cast.
>>>
>>> Per C99, those are the same type.
>>
>> To be exact C99 6.7.3.8 says something a little different:
>>
>> "If the specification of an array type includes any type qualifiers, the
>> element type is so qualified, not the array type."
>>
>> So it seems to exclude the existence of qualified array type...
> 
> Err, "int const (*)[2]" isn't a qualified array type... it's just an
> equivalent way of writing "const int (*)[2]".   But yes, the reason
> it's printed differently is due to the internal representation.

Ok, so unfortunately we have an internal representation that is
incongruent with C standard. This is related to efficiency issues?

>> Does this means that we might encounter all the possible combinations
>> (i.e. element with qualified/unqualified type inside nested arrays with
>> qualified/unqualified type) and that the qualifiers of arrays types and
>> item type should be merged to get a "normalized" type (not canonical)
>> where qualifiers are pushed to the item type as standard mandates?
>>
>> There is a method to get such type?
> 
> Why would you need such a type?

Consider this example:

struct S {
  volatile int a[2];
};

void foo(void) {
  const struct S* ps;
  &ps->a;
}

The type of &ps->a has a volatile qualifier attached to builtin int type
and a const qualifier attached to array type.

It seems to me rather obvious that this is an undesiderable situation
for library client that ask a sensible type for an Expr AST node.

Note also that methods like QualType::getCVRQualifiersThroughArrayTypes
does not handle properly this situation and obtain the wrong result.

To tell you the truth I don't see many reasons to synthesize array Types
with qualifiers instead to push the qualifiers in the right place, but
probably I'm missing something...




More information about the cfe-dev mailing list