473,379 Members | 1,252 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,379 software developers and data experts.

const array of const pointers as a parameter

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?
Oct 18 '06 #1
6 8280
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

Spoon wrote:
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?
Oct 18 '06 #2
Spoon schrieb:
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?
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.

Oct 18 '06 #3
Spoon wrote:
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.
...
The function parameter declaration is equivalent to 'const int* const* list'.
The type of actual argument (array 'p') decays to 'int**'. In other words, you
are trying to initialize an object of type 'const int* const*' with a value of
type 'int**'. This is not allowed by const-correctness rules of C language. The
culprit is the first 'const' from the left. C language allows you to "add" a
'const' at the first level of indirection, but not at any deeper level of
indirection. I.e. it is OK to convert 'int**' to 'int* const*', but it is not OK
to convert it to either 'const int**' or 'const int* const*'.

The rationale behind this is described in the following C++ (sic) FAQ entry

http://www.parashift.com/c++-faq-lit...html#faq-18.17

This is a C++ FAQ entry, but it does explain the issue very well. (There's also
a similar example in C99 standard.) However, C++ language adopted a more
elaborate behavior in this case and, as a result, C++ actually _allows_ the
'int**' to 'const int* const*' conversion (still disallowing the conversion to
'const int**'). C language decided to stay with a more primitive/simplified
specification, meaning that 'int**' to 'const int* const*' conversion is
outlawed in C, even though it's harmless from the const-correctness point of view.

--
Best regards,
Andrey Tarasevich
Oct 18 '06 #4
On 2006-10-18, Spoon <de*****@localhost.comwrote:
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?
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.
Oct 18 '06 #5

Spoon wrote:
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];
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).
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?
Oct 18 '06 #6
Andrey Tarasevich <an**************@hotmail.comwrote:
>
This is a C++ FAQ entry, but it does explain the issue very well. (There's also
a similar example in C99 standard.) However, C++ language adopted a more
elaborate behavior in this case and, as a result, C++ actually _allows_ the
'int**' to 'const int* const*' conversion (still disallowing the conversion to
'const int**'). C language decided to stay with a more primitive/simplified
specification, meaning that 'int**' to 'const int* const*' conversion is
outlawed in C, even though it's harmless from the const-correctness point of view.
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
Oct 18 '06 #7

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

6
by: Stephane Vollet | last post by:
Can someone tell me what's wrong with my code here? When compiling, it says : error C2143: syntax error : missing ';' before '*' error C2501: 'Tcase' : missing storage-class or type specifiers...
10
by: Evangelista Sami | last post by:
hello i haven't touch any C code for long time and i dont remember how to declare an array of pointers on functions. i have tried this : ----------------------- 35 void firing_1 36 (firing f,...
2
by: Steve | last post by:
I want an initializer for an array of pointers to arrays of strings. So I can do something like this: const char *t1 = { "a", "b", "c", NULL }; const char *t2 = { "p", "q", NULL }; const char...
1
by: electric sheep | last post by:
Hi, can somebody explain the following syntax to me. This is straight from a gnu info file: int main(void) { /* Hashed form of "GNU libc manual". */ const char *const pass =...
7
by: Frank M. | last post by:
I'm trying to declare an array of pointers to structures so that I can make the last element a NULL pointer. I figure that it would more easily allow my library routines to know when to stop...
24
by: kevin.hall | last post by:
Is char** (or char*) implicitly convertible to 'const char * const *'? I couldn't find anything about it in the standard. MSVS 8.0 allows this. I'm curious if I'll run into trouble with other...
5
by: Milan Cvetkovic | last post by:
Hi, Recently I came accross a weird bug in my code which turned to be my missunderstanding of arrays in C++. It all boils down to the small example: template<class ITER> const char* gggg...
23
by: sandy | last post by:
I need (okay, I want) to make a dynamic array of my class 'Directory', within my class Directory (Can you already smell disaster?) Each Directory can have subdirectories so I thought to put these...
5
by: whiskers | last post by:
Hello, gurus. I spent an hour looking for the answer to this and couldn't find one that pleased me (I don't want to use a base class, which seems to be a solution). So I have a function that...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.