Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   Re: Simple const question (http://www.velocityreviews.com/forums/t314784-re-simple-const-question.html)

Thomas Matthews 08-15-2003 10:02 PM

Re: Simple const question
 
Matt Gregory wrote:
> How do I declare this so I can use it as a non-const array of
> const char *?
>
> char **p;
>


You want to convert
a pointer to an array {pointer} of char
to
a pointer to an array of const char.

Noting that the declaration is sometimes easier read
right to left, my guess is:
char const * * p;
Which I believe reads as:
a pointer to a pointer to const char.


Just thinking out loud:
typedef char const * ptr_to_const_char;

An array of const char *:
ptr_to_const_char q[];

Decomposing an array to a pointer:
ptr_to_const_char *p1;

Replacing the "ptr_to_const_char" with the typedef
contents yields:
char const * *p2;

I think this is your solution:
char const * * p;

{If I'm wrong, somebody will correct me.
Ah, the true purpose of the newsgroup.}

--
Thomas Matthews
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html


Matt Gregory 08-15-2003 10:38 PM

Re: Simple const question
 
Thomas Matthews wrote:

> Matt Gregory wrote:
>
>> How do I declare this so I can use it as a non-const array of
>> const char *?
>>
>> char **p;
>>

>
> You want to convert
> a pointer to an array {pointer} of char
> to
> a pointer to an array of const char.
>
> Noting that the declaration is sometimes easier read
> right to left, my guess is:
> char const * * p;
> Which I believe reads as:
> a pointer to a pointer to const char.
>
>
> Just thinking out loud:
> typedef char const * ptr_to_const_char;
>
> An array of const char *:
> ptr_to_const_char q[];
>
> Decomposing an array to a pointer:
> ptr_to_const_char *p1;
>
> Replacing the "ptr_to_const_char" with the typedef
> contents yields:
> char const * *p2;
>
> I think this is your solution:
> char const * * p;
>
> {If I'm wrong, somebody will correct me.
> Ah, the true purpose of the newsgroup.}


Thanks for the explanation. I've always read multiple *'s from
left to right, but you've clearly demonstrated to me that that
is wrong (I'll have to save this post on my hard drive so I can
remember :-). But I still can't get rid of this MSVC warning:
"different 'const' qualifiers" in my call to free().

I'm basically trying to do:

char const **arg_ptrs;

arg_ptrs = malloc(10 * sizeof(char *));

/* play with arg_ptrs */
arg_ptrs[0] = argv[2];

free(arg_ptrs);

I've tried putting the const in four different places. Am I
trying to do the impossible or something? I shouldn't be
getting that warning from free(), I don't think, because I'm
trying to free the non-const part of arg_ptrs...not to mention
the "'free' : pointer mismatch for actual parameter 1" warning
I'm getting.

It's been so long since I've used straight C, I guess I'm kinda
rusty.

Thanks!
Matt Gregory


CBFalconer 08-16-2003 02:35 AM

Re: Simple const question
 
Matt Gregory wrote:
>

.... snip ...
>
> Thanks for the explanation. I've always read multiple *'s from
> left to right, but you've clearly demonstrated to me that that
> is wrong (I'll have to save this post on my hard drive so I can
> remember :-). But I still can't get rid of this MSVC warning:
> "different 'const' qualifiers" in my call to free().
>
> I'm basically trying to do:
>
> char const **arg_ptrs;
>
> arg_ptrs = malloc(10 * sizeof(char *));
>
> /* play with arg_ptrs */
> arg_ptrs[0] = argv[2];
>
> free(arg_ptrs);
>
> I've tried putting the const in four different places. Am I
> trying to do the impossible or something? I shouldn't be
> getting that warning from free(), I don't think, because I'm
> trying to free the non-const part of arg_ptrs...not to mention
> the "'free' : pointer mismatch for actual parameter 1" warning
> I'm getting.


You are inconsistent. A few typedefs may clear things up. I
believe the item you want to make constant is the pointer to a
char.

typedef char *cp;

typedef const cp ccp;
/* I hope a ccp is a (ptr to char) which should not be altered */

ccp *arg_ptrs;

arg_ptrs = malloc(somenumber * sizeof(*arg_ptrs));
/* notice what the sizeof is measuring */

And now you have a place to store somenumber of things of type
ccp. However you can't do it, because the only place you can
initialize such (const) values is in an initialization statement,
and you didn't do it. So you will have to do something else.
Maybe:

ccp arg_ptrs[] = {&item1, &item2, &item3 ....};

which means there will have to have been earlier declarations of:

char item1[SOMESIZE];
/* etc. to resolve those unchanging pointers */

*************
I am quite prepared to be corrected, as I have just been rambling.
************

--
Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!



Kevin Easton 08-16-2003 03:08 AM

Re: Simple const question
 
Matt Gregory <msgregory.nospamy.@earthlink.net> wrote:
[...]
> Thanks for the explanation. I've always read multiple *'s from
> left to right, but you've clearly demonstrated to me that that
> is wrong (I'll have to save this post on my hard drive so I can
> remember :-). But I still can't get rid of this MSVC warning:
> "different 'const' qualifiers" in my call to free().
>
> I'm basically trying to do:
>
> char const **arg_ptrs;
>
> arg_ptrs = malloc(10 * sizeof(char *));
>
> /* play with arg_ptrs */
> arg_ptrs[0] = argv[2];
>
> free(arg_ptrs);
>
> I've tried putting the const in four different places. Am I
> trying to do the impossible or something? I shouldn't be
> getting that warning from free(), I don't think, because I'm
> trying to free the non-const part of arg_ptrs...not to mention
> the "'free' : pointer mismatch for actual parameter 1" warning
> I'm getting.


This is actually a somewhat misleading warning from MSVC. Your free is
effectively assigning a "const char **" pointer to a "void *" - but
there's nothing wrong with this. The "const char **" points to a
non-const object (which itself has type "const char *"), so it should be
fine to assign it to "void *".

On the other hand, if you were trying to pass a "const char *" then you
would expect a similar warning - a "const char *" points to a
const-qualified object, and a "void *" points to a non-const object. In
the particular case of free, this warning doesn't really make sense, and
it should probably have been defined as taking a "const void *" argument
in the first place - I don't know why it wasn't.

In either case, just cast the value you're passing to free, the warning
is benign.

free((void *)arg_ptrs);

Or, if you are under religious orders to avoid pointer casts entirely,
you can save a pointer to the original malloc'ed memory:

void *arg_ptrs_mem;
const char **arg_ptrs;

arg_ptrs = arg_ptrs_mem = malloc(10 * sizeof(char *));

and then use that pointer in the free:

free(arg_ptrs_mem);

- Kevin.

Matt Gregory 08-16-2003 05:23 AM

Re: Simple const question
 
(only snipping because it looks really long to me at the moment and
I have no comment, except that using typedef's for pointers really
confuses me - I have to mentally deconstruct the typedef's to
understand what they mean, anyway)

CBFalconer wrote:
>
> *************
> I am quite prepared to be corrected, as I have just been rambling.
> ************


Sorry, sorry, it's my fault. I should have been more explicit. I'm
converting my command line argument processor from C++ to C. If the
program takes trailing arguments, these are pushed onto a queue so
they can be retrieved one at a time later. The queue is just a
generic array-based char* queue, so it's given a size when it's
created, and it's allocated on the heap. So, you know, I basically
have this...

int main(int argc, const char *argv[])

....and this...

const char **p = malloc(n * sizeof(char *));

....wherever the 'const' is supposed to go. I guess that looks good.
I'll stick with the Early Colonial look.

I know I could just rearrange the pointers in argv[] so all the
trailing arguments are at the end, but, well, I just don't feel like
figuring that out. I've spent enough time on this already. But,
now that I say that, I suppose tomorrow I'll be compelled by the
forces of perfectionism to figure out the pointer shuffle method and
get rid of the damn queue.


Kevin Easton wrote:
>> In either case, just cast the value you're passing to free, the warning
>> is benign.
>>
>> free((void *)arg_ptrs);


I didn't want to do that because I thought I had a real problem
with my code. But I guess my programming skills are just so
complex and advanced that I'm completely outwitting the compiler.
I'll try to tone it down.

Matt Gregory


Martijn 08-16-2003 08:57 AM

Re: Simple const question
 
> This is actually a somewhat misleading warning from MSVC. Your free
> is effectively assigning a "const char **" pointer to a "void *" - but
> there's nothing wrong with this. The "const char **" points to a
> non-const object (which itself has type "const char *"), so it should
> be fine to assign it to "void *".


[snipped]

> free((void *)arg_ptrs);
>
> Or, if you are under religious orders to avoid pointer casts entirely,
> you can save a pointer to the original malloc'ed memory:
>
> void *arg_ptrs_mem;
> const char **arg_ptrs;
>
> arg_ptrs = arg_ptrs_mem = malloc(10 * sizeof(char *));
>
> and then use that pointer in the free:
>
> free(arg_ptrs_mem);


Wouldn't that still be assigning a "const char **" to a "void *"? If the
compiler complained about this in the first place (which I feel it
shouldn't), you will have only moved the warning to a different place :)

--
Martijn
http://www.sereneconcepts.nl



Kevin Easton 08-16-2003 02:10 PM

Re: Simple const question
 
Martijn <subscription-NOSPAM-101@hotnofiltermail.com> wrote:
>> This is actually a somewhat misleading warning from MSVC. Your free
>> is effectively assigning a "const char **" pointer to a "void *" - but
>> there's nothing wrong with this. The "const char **" points to a
>> non-const object (which itself has type "const char *"), so it should
>> be fine to assign it to "void *".

>
> [snipped]
>
>> free((void *)arg_ptrs);
>>
>> Or, if you are under religious orders to avoid pointer casts entirely,
>> you can save a pointer to the original malloc'ed memory:
>>
>> void *arg_ptrs_mem;
>> const char **arg_ptrs;
>>
>> arg_ptrs = arg_ptrs_mem = malloc(10 * sizeof(char *));
>>
>> and then use that pointer in the free:
>>
>> free(arg_ptrs_mem);

>
> Wouldn't that still be assigning a "const char **" to a "void *"? If the
> compiler complained about this in the first place (which I feel it
> shouldn't), you will have only moved the warning to a different place :)


Where?

As far as I can see, there are two assignments - the first from void *
to void *, and the second from void * to const char **.

- Kevin.



All times are GMT. The time now is 05:06 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.