Re: Simple const question

Discussion in 'C Programming' started by Thomas Matthews, Aug 15, 2003.

  1. 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
     
    Thomas Matthews, Aug 15, 2003
    #1
    1. Advertising

  2. Thomas Matthews

    Matt Gregory Guest

    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
     
    Matt Gregory, Aug 15, 2003
    #2
    1. Advertising

  3. Thomas Matthews

    CBFalconer Guest

    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 () ()
    Available for consulting/temporary embedded and systems.
    <http://cbfalconer.home.att.net> USE worldnet address!
     
    CBFalconer, Aug 16, 2003
    #3
  4. Thomas Matthews

    Kevin Easton Guest

    Matt Gregory <> 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.
     
    Kevin Easton, Aug 16, 2003
    #4
  5. Thomas Matthews

    Matt Gregory Guest

    (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
     
    Matt Gregory, Aug 16, 2003
    #5
  6. Thomas Matthews

    Martijn Guest

    > 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
     
    Martijn, Aug 16, 2003
    #6
  7. Thomas Matthews

    Kevin Easton Guest

    Martijn <> 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.
     
    Kevin Easton, Aug 16, 2003
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    11
    Views:
    1,124
  2. Javier
    Replies:
    2
    Views:
    584
    James Kanze
    Sep 4, 2007
  3. 0m
    Replies:
    26
    Views:
    1,142
    Tim Rentsch
    Nov 10, 2008
  4. fungus
    Replies:
    13
    Views:
    901
    fungus
    Oct 31, 2008
  5. Replies:
    2
    Views:
    545
    Andrew Koenig
    Feb 9, 2009
Loading...

Share This Page