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

Eli Friedman eli.friedman at gmail.com
Sat Oct 23 11:45:54 PDT 2010


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.

>>> We thought there was an implementation invariant whereby qualifiers of
>>> array types, when stored in clang::Expr nodes, were automatically pushed
>>> on the corresponding array element type.
>>> Is this NOT the case?
>>
>> For canonical types, yes... for non-canonical types, no.  The two
>> types in question here should probably be fixed to print the same way,
>> though... it's confusing to have what appears to be the same type
>> print in different ways.
>
> However, if the current behaviour is confirmed to be intentional, we
> should taken in account that the type stored along with Expr nodes might
> have qualifiers also in array type.
>
> 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?

-Eli




More information about the cfe-dev mailing list