const array of const pointers as a parameter

const array of const pointers as a parameter

Post by Spoo » Fri, 20 Oct 2006 00:21:17


Hello,

I don't understand why gcc barks at me in this situation:

$ cat foo.c
extern void func(const int * const list[], int nent);

int main(void)
{
int *p[5];
func(p, 5);
return 0;
}

$ gcc -Wall -std=c89 -c foo.c
foo.c: In function `main':
foo.c:6: warning: passing arg 1 of `func' from incompatible pointer type

AFAIU, func promises not to change the values pointed to by the pointers
in the array (i.e. *list[2] = 666 is illegal) AND not to change the
pointers themselves (i.e. list[2] = NULL is also illegal).

I don't understand what the compiler dislikes about p.

Could someone enlighten me?
 
 
 

const array of const pointers as a parameter

Post by Dark » Fri, 20 Oct 2006 00:48:35

Hm. I myself too had trouble with consts pretty much the same way you
do now. As far as I can recall, multiple consts in the same expression
are not allowed by ANSI. However, lots of things seem not to be allowed
by ANSI and yet are quite normal in practice.

Anyway, my humble opinion is that you should try adding another const
at the and of your "list" expression, like in: const int * const * list
const. That way you declare list to be constant, too, which is true
because what you've got down there is a static array, which is actually
a constant pointer to another pointer.

I would try it myself but I don't have Linux here at work.

Bye,

Darko

 
 
 

const array of const pointers as a parameter

Post by arne » Fri, 20 Oct 2006 01:49:21

Spoon schrieb:


What about changing

int *p[5];

to

const int *p[5]; ?


The function expects an array of const pointers to const ints, but you
pass an array of pointers to ints.
 
 
 

const array of const pointers as a parameter

Post by A. Bolmarc » Fri, 20 Oct 2006 03:11:38


The assignment constraint in the C89 specification being used in this
case is

both operands are pointers to qualified or unqualified types verisons
of compatible types, and the type pointed to by the left has all the
qualifiers as the type pointed to by the right

Also, according th the C89 specification

For two qualified types to be compatible, both shall have the identical
qualified versions of a compatible type

The argument type is pointerTo-pointerTo-int and the parameter type is
pointerTo-pointerTo-const-int. According to the C89 specification
a pointerTo-int is not compatible with pointerTo-const-int because they
are not identically qualified.

The assignment constraint allows the parameter to have additional
"top-level" pointer qualifiers that the argument does not have. This
allows a (* int) argument to be assigned to a (const * int) parameter.
However, that constraint does not apply to "inner-level" pointers which
need to be identically qualified.
 
 
 

const array of const pointers as a parameter

Post by John Bod » Fri, 20 Oct 2006 03:15:32


This is not an array of constant pointers. That's why you're getting
barked at.

If you declare it as

int const *p[5];

the code should compile (it does for me, anyway). Whether that's what
you really *want* to do is an open question (I suspect it isn't).
 
 
 

const array of const pointers as a parameter

Post by lawrence.j » Fri, 20 Oct 2006 07:09:19


In particular, the original C rules were developed before the C++ rules
had been worked out. Once they were, the way C++ describes the common
language is sufficiently different from the way C describes it that the
rules could not just be lifted verbatim but would have to be rewritten
(in particular, I seem to recall some unrelated handwaving in the C++
standard that happens to make arrays work out right that does not exist
in the C standard). Also, C added the restrict type qualifier, which
complicates the rules since it does not work the same way as const and
volatile do. So far as I know, no one has worked out the rules with
restrict included.

-Larry Jones

Hey Doc, for 10 bucks I'll make sure you see those kids in the
waiting room again real soon! -- Calvin