User account creation filtered due to spam.

Bug 31887 - bad warning converting qualified void* to qualified array pointer
Summary: bad warning converting qualified void* to qualified array pointer
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: unknown
: P3 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2007-05-10 05:43 UTC by Ken Raeburn
Modified: 2014-02-26 02:03 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Ken Raeburn 2007-05-10 05:43:32 UTC
/* With revision 124583, using compiler command "./xgcc -B./ -O -S ~/qual.c"
   in the "prev-gcc" directory once it's been updated with the current
   binaries, the compiler complains:

   qual.c:11: warning: passing argument 1 of 'foo' discards qualifiers from pointer target type

*/
typedef unsigned char block[8];
extern int foo(const block *in, block *out);
int bar (const void *p, void *q) {
  return foo (p, q);		/* line 11 */
}

I'm not 100% sure about how array types and qualifiers mix, but I believe this is correct code, and that there shouldn't be a warning.
Comment 1 Andrew Pinski 2007-05-11 00:00:16 UTC
I think only "void*" can be done with an implicat cast so we go from const void* to void* and then to const block*.
Comment 2 Ken Raeburn 2007-05-11 08:05:52 UTC
Subject: Re:  bad warning converting qualified void* to qualified array pointer

On May 10, 2007, at 19:00, pinskia at gcc dot gnu dot org wrote:
> I think only "void*" can be done with an implicat cast so we go  
> from const
> void* to void* and then to const block*.

ISO/IEC 9899-1999 section 6.5.16.1 (assignment constraints) includes:

  - one operand is a pointer to an object or incomplete type and the  
other is a pointer to a qualified or unqualified version of void, and  
the type pointed to by the left has all the qualifiers of the type  
pointed to by the right.

So I'm pretty sure we don't automatically lose on the const-ness in  
the general case.  What I'm less sure about is how the array type  
plays into it.  According to 6.7.3, "const block" means "array [8] of  
const unsigned char", so is there an argument to be made that  
assigning a pointer-to-const value to an lvalue of type pointer to an  
unqualified array type (containing a type that happens to be const- 
qualified) isn't allowed?  I don't think it would be logical, but  
that doesn't guarantee that that's how the standard actually works.

Ken
Comment 3 Ken Raeburn 2007-08-15 06:03:18 UTC
Section 6.7.3 says:  "If the specification of an array type includes any type qualifiers, the element type is so-qualified, not the array type."  The more I think about it, the more I think the compiler is technically correct, though I think this is probably a bug in the standard.

I brought this up on comp.std.c a couple weeks or so ago, though, and while Doug Gwyn, whose interpretation on these things I generally respect, seemed to indicate that my current interpretation is wrong (and that it should indeed be "const array of 8 chars"), he didn't provide references to that effect, so I'm not sure where that interpretation comes from.
Comment 4 Jed Brown 2008-11-17 12:24:07 UTC
There is no way to qualify an array type, but this sort of conversion is very useful.  For instance, the optimizer produces better code for

void foo(const double a[], int m, int n) {
  const double (*b)[n] = (const double(*)[n])a;
  /* use b[i][j] in inner loops */
}

than when `a[i*n+j]' is used (without manually hoisting arithmetic out of inner loops).  With -Wcast-qual, a warning is given since the qualifier does not apply to the array type, only the elements.  Note that this example is very similar to the example given in http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf page 87 (physical page 94).  Clearly the cast above should be possible, although there is no way to express it in a way that is compatible with C99 paragraph 6.7.3.8.  I propose that -Wcast-qual promote qualifiers on array elements to the array itself when determining whether a cast discards qualifiers.  That is, not warn for casts like the one above.
Comment 5 Andrew Pinski 2014-02-26 02:03:30 UTC
Invalid as qualifiers for arrays are not attached to the array type but rather to the element so there is no such thing as a const array.