[cfe-dev] ArrayType and qualifiers

John McCall rjmccall at apple.com
Fri Jan 28 13:29:27 PST 2011


On Jan 28, 2011, at 3:44 AM, Abramo Bagnara wrote:
> Il 28/01/2011 10:26, John McCall ha scritto:
>> Hmm.  Actually, I think I'm wrong. :)  In C, array types are never
>> qualified, only their element types;  so while my argument is sound in
>> principle, it's not actually following the specification.
>> 
>> That said, this is quite arguably a flaw in the specification, and it's
>> been so argued in quite a few places, as mentioned and linked from here:
>>  http://stackoverflow.com/questions/305293/constant-array-types-in-c-flaw-in-standard
>> so we should probably add a -pedantic warning for this at least.  I've
>> file http://llvm.org/bugs/show_bug.cgi?id=9082 to track this.
> 
> stackoverflow seems to refers to case of cast from pointer to int to
> pointer of array of int, while the example I wrote is about

Right, that post on stackoverflow is about an explicit cast that gives a warning under GCC because it supposedly removes qualifiers, for the reason I give below.  Since that diagnostic is supposed to be a QoI, the-programmer-is-doing-something-dangerous warning, GCC is wrong to produce it *regardless* of how the standard treats qualifiers, because the behavior in question is not actually unsafe.  Put another way, the first responsibility of a diagnostic like that should be utility to programmers, not pedantry.  That said, I'm sure it's just a lazy implementation.

> I don't see how 6.3.2.3p2 might be read differently from what you has
> written in previous email.
> 
> Take this modified example:
> 
> void f() {
>  const int (*x)[1] = 0;
>  int (*y)[1] = 0;
>  x = y;
> }
> 
> typedef int Type[1];
> 
> void g() {
>  const Type* x = 0;
>  Type* y = 0;
>  x = y;
> }
> 
> 6.3.2.3p2 says: For any qualifier q, a pointer to a non-q-qualified type
> may be converted to a pointer to the q-qualified version of the type;
> the values stored in the original and converted pointers shall compare
> equal.

The question is whether the const-qualified version of int[1] is const int[1], or whether it's the formally-impossible type int[1] const.  I think the most likely interpretation is the latter, which would prohibit this conversion.  Basically, the standard follows clang's old canonical type representation, except that qualifier queries aren't supposed to look through array types.

I think that's incontrovertibly wrong as an abstract point of language design, so I have no problems with the fact that we're Doing The Right Thing (tm) instead, but we probably should have a compatibility / pedantic warning about it, which is why I filed PR9082.

> Don't be sorry, every good technical choice about AST is very welcome
> for us and I've already adapted our code to restore qualifier position
> where standard mandates, so everything is working again.

Glad to hear it wasn't too difficult.

> I've written to convince myself this was indeed a good technical choice
> and to be honest I've still doubts for some techinical reasons:
> 
> 1) incongruence on representations of canonical types and syntactical
> type about position of qualifiers

Well, this was true before in the general case, but I see your point.

> 2) the element type AST node has not the qualifiers that standard mandates

I'm okay with having a slightly different representation from the standard in this case.

> 4) fragile clang API, where we risk everytime to lose element qualifiers
> descending on the type

This is already true of the most common case, i.e. clients that walk non-canonical types, so unfortunately everyone just has to know that array types are special.  Once that's true, I think be able to add and remove qualifiers easily on canonical types is really a blessing.

John.



More information about the cfe-dev mailing list