[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