Bug 33076 - Warning when passing a pointer to a const array to a function that expects a pointer to a non-cast one
Summary: Warning when passing a pointer to a const array to a function that expects a ...
Status: RESOLVED DUPLICATE of bug 16602
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.1.3
: P3 minor
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-08-15 03:45 UTC by Martín Ferrari
Modified: 2007-11-20 21:53 UTC (History)
6 users (show)

See Also:
Host: i486-linux-gnu
Target: i486-linux-gnu
Build: i486-linux-gnu
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 Martín Ferrari 2007-08-15 03:45:20 UTC
Sorry if I'm misunderstanding something or this is a FAQ, but I couldn't find any reference, except for a unanswered mail with the same problem from 2000 at http://gcc.gnu.org/ml/gcc-bugs/2000-10/msg00337.html (and I don't find it in bugzilla either). The code looks semantically correct to me, the function declares that it won't touch the data and I'm passing a non-const data. If the typecast is not to an array, the warning goes away.

Thanks.

Build options:

../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.1.3 --program-suffix=-4.1 --enable-__cxa_atexit --enable-clocale=gnu --enable-libstdcxx-debug --enable-mpfr --with-tune=i686 --enable-checking=release i486-linux-gnu

Command line:

$ gcc -c /home/martin/test.c
/home/martin/test.c: In function ‘bar’:
/home/martin/test.c:8: warning: passing argument 1 of ‘foo’ from incompatible pointer type

Code:

typedef int caca[3];
void foo (const caca* p);
void bar(caca *c) {
	foo(c);
}
Comment 1 Ken Raeburn 2007-08-15 06:13:43 UTC
Subject: Re:   New: Warning when passing a pointer to a const array to a function that expects a pointer to a non-cast one

On Aug 14, 2007, at 23:45, martin dot ferrari at gmail dot com wrote:
> Sorry if I'm misunderstanding something or this is a FAQ, but I  
> couldn't find
> any reference, except for a unanswered mail with the same problem  
> from 2000 at
> http://gcc.gnu.org/ml/gcc-bugs/2000-10/msg00337.html (and I don't  
> find it in
> bugzilla either). The code looks semantically correct to me, the  
> function
> declares that it won't touch the data and I'm passing a non-const  
> data. If the
> typecast is not to an array, the warning goes away.


> /home/martin/test.c:8: warning: passing argument 1 of ‘foo’ from  
> incompatible
> pointer type

> typedef int caca[3];
> void foo (const caca* p);
> void bar(caca *c) {
>         foo(c);
> }

I think this might be related to the bug report I filed in 31887 --  
and I'm starting to think that we might both be wrong.

Weird as it seems, my reading of the C spec, section 6.7.3 says that  
the qualifier (const, in both our cases, but it would apply to  
volatile as well) applies only to the array element type, and does  
*not* apply to the array type itself.  So this isn't like assigning a  
"char *" value to a "const char *"; you're dealing with pointers to  
two different array types (which happen to have similar but  
differently-qualified element types).

I'm not 100% sure I believe this interpretation, because it seems to  
needlessly prohibit perfectly reasonable code, and when I asked on  
comp.std.c a couple weeks back, I got some mixed feedback.  But at  
the moment, that's my reading of the spec....

Ken
Comment 2 Ken Raeburn 2007-08-15 06:15:20 UTC
Subject: Re:   New: Warning when passing a pointer to a const array to a function that expects a pointer to a non-cast one

On Aug 14, 2007, at 23:45, martin dot ferrari at gmail dot com wrote:
> Sorry if I'm misunderstanding something or this is a FAQ, but I  
> couldn't find
> any reference, except for a unanswered mail with the same problem  
> from 2000 at
> http://gcc.gnu.org/ml/gcc-bugs/2000-10/msg00337.html (and I don't  
> find it in
> bugzilla either). The code looks semantically correct to me, the  
> function
> declares that it won't touch the data and I'm passing a non-const  
> data. If the
> typecast is not to an array, the warning goes away.


> /home/martin/test.c:8: warning: passing argument 1 of ‘foo’ from  
> incompatible
> pointer type

> typedef int caca[3];
> void foo (const caca* p);
> void bar(caca *c) {
>         foo(c);
> }

I think this might be related to the bug report I filed in 31887 --  
and I'm starting to think that we might both be wrong.

Weird as it seems, my reading of the C spec, section 6.7.3 says that  
the qualifier (const, in both our cases, but it would apply to  
volatile as well) applies only to the array element type, and does  
*not* apply to the array type itself.  So this isn't like assigning a  
"char *" value to a "const char *"; you're dealing with pointers to  
two different array types (which happen to have similar but  
differently-qualified element types).

I'm not 100% sure I believe this interpretation, because it seems to  
needlessly prohibit perfectly reasonable code, and when I asked on  
comp.std.c a couple weeks back, I got some mixed feedback.  But at  
the moment, that's my reading of the spec....

Ken
Comment 3 jbeulich 2007-09-19 09:39:27 UTC
Isn't this the same as 16602 (which I don't really understand why it was rejected as invalid)? Also, if this *is* invalid, then what proper mechanism does one have to express what is intended here? And why does similar code compile warning free in C++?
Comment 4 Andreas Schwab 2007-09-19 09:47:40 UTC

*** This bug has been marked as a duplicate of 16602 ***
Comment 5 jsm-csl@polyomino.org.uk 2007-09-19 19:54:33 UTC
Subject: Re:  Warning when passing a pointer to a const array
 to a function that expects a pointer to a non-cast one

On Wed, 19 Sep 2007, jbeulich at novell dot com wrote:

> Isn't this the same as 16602 (which I don't really understand why it was
> rejected as invalid)? Also, if this *is* invalid, then what proper mechanism
> does one have to express what is intended here? And why does similar code
> compile warning free in C++?

Neither C nor C++ have qualified array types, only arrays of qualified 
element types, but C++ has different rules from C regarding conversions 
involving qualifiers, which allow some conversions (involving arrays or 
pointers to pointers) not allowed in C.

Comment 6 Jozef Behran 2007-09-26 12:06:28 UTC
> Neither C nor C++ have qualified array types, only arrays of qualified 
> element types, but C++ has different rules from C regarding conversions 
> involving qualifiers, which allow some conversions (involving arrays or 
> pointers to pointers) not allowed in C.

Could you give me reference in the C standard where this is stated ? The section 6.7.3, paragraph 8, says nothing about C/C++ not having qualified array types, it only says that a qualifier applied to an array type holds for the element type of the array type (these two are not the same things, see bug 16602 for more discussion about the topic).
Comment 7 Jozef Behran 2007-09-26 12:18:13 UTC
> Neither C nor C++ have qualified array types, only arrays of qualified 
> element types, but C++ has different rules from C regarding conversions 
> involving qualifiers, which allow some conversions (involving arrays or 
> pointers to pointers) not allowed in C.

And another point: Whether C/C++ have or don't have qualified array types, still the difference between the "const caca *" and "caca *" types is a "const" qualifier being applied to some part of the "caca *" base type. Therefore the types must be compatible when the automatic type conversion involved only adds "const" qualifiers to the type. Therefore the warnings are not legitimate.
Comment 8 jsm-csl@polyomino.org.uk 2007-09-26 12:38:59 UTC
Subject: Re:  Warning when passing a pointer to a const array
 to a function that expects a pointer to a non-cast one

On Wed, 26 Sep 2007, jozef dot behran at krs dot sk wrote:

> Could you give me reference in the C standard where this is stated ? The
> section 6.7.3, paragraph 8, says nothing about C/C++ not having qualified array
> types, it only says that a qualifier applied to an array type holds for the
> element type of the array type (these two are not the same things, see bug
> 16602 for more discussion about the topic).

That which you quote means there is no way to put a qualifier on the array 
type because any attempt to do so puts it on the element type instead.  
That there are no qualified array types is simply the logical conclusion 
from there being no C syntax to write one.  Note "not the array type" in 
that paragraph.

The question of whether abstractly one might imagine a qualified array 
type in C despite the lack of syntax to describe one, and how such a type 
(notwithstanding the lack of syntax to describe it) would behave if it 
were to exist, is not an interesting one in the absence of implementation 
extensions to define such a type.

Comment 9 jsm-csl@polyomino.org.uk 2007-09-26 12:42:42 UTC
Subject: Re:  Warning when passing a pointer to a const array
 to a function that expects a pointer to a non-cast one

On Wed, 26 Sep 2007, jozef dot behran at krs dot sk wrote:

> And another point: Whether C/C++ have or don't have qualified array types,
> still the difference between the "const caca *" and "caca *" types is a "const"
> qualifier being applied to some part of the "caca *" base type. Therefore the
> types must be compatible when the automatic type conversion involved only adds
> "const" qualifiers to the type. Therefore the warnings are not legitimate.

Read the C FAQ.  You can't pass a "char **" where a "const char **" is 
expected either in C.  That's how the language works.

http://c-faq.com/ansi/constmismatch.html

C++ allows certain cases C doesn't that can be shown to be safe, as noted 
in that FAQ.  A proposal to make C use the C++ rules was rejected in the 
course of C99 development.

Comment 10 Lehtonen, Matti 2007-11-20 21:53:21 UTC
This code piece cannot compiled without warnings or errors.

/*! Presentation of transformation matrix */
typedef coordinate_t    transform_matrix_t[ 4 ][ 4 ];
...
void
  transform_concat
  (
    transform_matrix_t        transform,
    transform_matrix_t const  transform1,
    transform_matrix_t const  transform2
  );
...
void
  transform_rotate
  (
    transform_matrix_t    transform,
    real_t const          angles[ 3 ]
  )
{
  transform_matrix_t
    temp;

...
  transform_concat( transform, transform, temp );
...
}
Without casts I got two warnings:
warning: passing argument 2 of ‘transform_concat’ from incompatible pointer type
warning: passing argument 3 of ‘transform_concat’ from incompatible pointer type

And if arument 2 and 3 are casted as
  transform_concat( transform, (const transform_matrix_t) transform, (const transform_matrix_t) temp );

Then I got two errors:
error: cast specifies array type
error: cast specifies array type