423,850 Members | 1,661 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 423,850 IT Pros & Developers. It's quick & easy.

const char ** argument

P: n/a
Hello. I have a doubt about argument conversion when passing arguments
to a function. I have a function like:

struct packet *pkt_interest(const char **usrs);

struct packet is defined elsewhere (it has no interest to show it here).
With that "const" modifier I want to state that usrs pointer will not
be changed inside the function.

Then, from the main program, I have this:

char *users[] = {
"alberto",
"juan",
"pepito",
NULL
};

struct packet *pkt = pkt_interest(users);

compiler throws the warning:
test_proto.c:23: warning: passing arg 1 of `pkt_interest' from
incompatible pointer type.

And I have to modify the users declaration to be "const char *users" or
make an explicit cast in the function call.

I though the const modifier in the funcion declaration was just a "hey,
i won't change your pointer, trust me" and could use a plain char **, in
a similar way as we use strcpy function (the second argument is a const
char *, but we can use a non-const char * with no problems).

¿Where's the difference with the const in strcpy and the const in my
pkt_interest?

TIA
--
Luis Alberto Giménez
JabberID: Si*******@bulmalug.net
GnuPG ID: 0x3BAABDE1
Nov 15 '05 #1
Share this Question
Share on Google+
3 Replies


P: n/a
Alberto Giménez wrote:
Hello. I have a doubt about argument conversion when passing arguments
to a function. I have a function like:

struct packet *pkt_interest(const char **usrs);

struct packet is defined elsewhere (it has no interest to show it here).
With that "const" modifier I want to state that usrs pointer will not
be changed inside the function.

Then, from the main program, I have this:

char *users[] = {
"alberto",
"juan",
"pepito",
NULL
};

struct packet *pkt = pkt_interest(users);

compiler throws the warning:
test_proto.c:23: warning: passing arg 1 of `pkt_interest' from
incompatible pointer type.

And I have to modify the users declaration to be "const char *users" or
make an explicit cast in the function call.

I though the const modifier in the funcion declaration was just a "hey,
i won't change your pointer, trust me" and could use a plain char **, in
a similar way as we use strcpy function (the second argument is a const
char *, but we can use a non-const char * with no problems).

¿Where's the difference with the const in strcpy and the const in my
pkt_interest?


In the second level of indirection.

Read the FAQ 11.10 on this topic
"Why can't I pass a char ** to a function which expects a
const char **?"

Search the usenet archives for comp.lang.c if this does not suffice.

Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 15 '05 #2

P: n/a
In article <4a**********@127.0.0.1>,
Alberto Giménez <al****@teleline.es> wrote:

[...]
Then, from the main program, I have this:

char *users[] = {
"alberto",
"juan",
"pepito",
NULL
};


The real issue is here. Try this:
char *users[] = {
"foo",
"bar",
NULL
};

users[1][2] = 'z';

This will crash since users[1] points to a read-only string (if the
compiler didn't warn you about that, it's a compiler bug). This is
really the difference between:

char *s1 = "foo"; /* a mistake */
and
char s2[] = "foo"; /* correct */

Given that you cannot modify "alberto", "juan", or "pepito", you should
have:

const char *users[] = { /* ... */ }

- Steve
Nov 15 '05 #3

P: n/a
Steve Checkoway wrote:
In article <4a**********@127.0.0.1>,
Alberto Giménez <al****@teleline.es> wrote:

[...]
Then, from the main program, I have this:
char *users[] = {
"alberto",
"juan",
"pepito",
NULL
};

The real issue is here. Try this:
char *users[] = {
"foo",
"bar",
NULL
};

users[1][2] = 'z';

This will crash since users[1] points to a read-only string (if the
compiler didn't warn you about that, it's a compiler bug).


Nope. String literals should not be modified as they could reside in
some sort of read-only storage but they are not guaranteed to be
non-modifiable.
In C, "a string" is not array 9 of const char but array 9 of char.
This is
really the difference between:

char *s1 = "foo"; /* a mistake */ ^^^^^^^^^^
This is not a mistake -- however, it is a Bad Idea.
and
char s2[] = "foo"; /* correct */

Given that you cannot modify "alberto", "juan", or "pepito", you should
have:

const char *users[] = { /* ... */ }


Yep. Depending on what you want to achieve, you could even declare
users as
const char *const users[]....
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
Nov 15 '05 #4

This discussion thread is closed

Replies have been disabled for this discussion.