Casting void * to void ** ?

Discussion in 'C Programming' started by Twister, Apr 21, 2006.

  1. Twister

    Twister Guest

    Hi All,

    I have a question which might sound very basic.

    I have a simple structure:

    struct simple{
    void *buffer;
    };
    typedef struct simple Simple;

    In my function I do this:

    void do_Something(){

    Simple *simp_struct;
    simp_struct->buffer = malloc(10 * sizeof(int *));

    call_func((void **)((int **)(simp_struct->buffer)));
    ....
    }

    The function call_func has this prototype:
    call_func(void **buf);

    I am confused with this piece of code:
    call_func((void **)((int **)(simp_struct->buffer)));

    What does this construct mean? How is that simp_struct->buffer
    (which is a void *) is being cast to a int** followed by a
    cast to void ** and passed to call_func ?

    Rgds.
    Mirage
     
    Twister, Apr 21, 2006
    #1
    1. Advertising

  2. Twister

    Twister Guest

    Twister wrote:
    > Hi All,
    >
    > I have a question which might sound very basic.
    >
    > I have a simple structure:
    >
    > struct simple{
    > void *buffer;
    > };
    > typedef struct simple Simple;
    >
    > In my function I do this:
    >
    > void do_Something(){
    >
    > Simple *simp_struct;
    > simp_struct->buffer = malloc(10 * sizeof(int *));
    >
    > call_func((void **)((int **)(simp_struct->buffer)));
    > ....
    > }
    >
    > The function call_func has this prototype:
    > call_func(void **buf);
    >
    > I am confused with this piece of code:
    > call_func((void **)((int **)(simp_struct->buffer)));
    >
    > What does this construct mean? How is that simp_struct->buffer
    > (which is a void *) is being cast to a int** followed by a
    > cast to void ** and passed to call_func ?
    >
    > Rgds.
    > Mirage


    I mistyped part of my previous mail:

    This piece of code:
    > I am confused with this piece of code:
    > call_func((void **)((int **)(simp_struct->buffer)));


    should be this:

    for(i=0; i<10 ;i++)
    call_func((void **)((int **)simp_struct->buffer + i));

    My question remains the same. What does the above
    construct mean?

    Rgds.
    Mirage
     
    Twister, Apr 21, 2006
    #2
    1. Advertising

  3. In article <k872g.27$>,
    Twister <> wrote:

    >struct simple{
    > void *buffer;
    >};
    >typedef struct simple Simple;


    >void do_Something(){
    >
    > Simple *simp_struct;


    simp_struct is an uninitialized pointer after that statement.

    > simp_struct->buffer = malloc(10 * sizeof(int *));


    But there you are using it as if it was initialized.
    simp_struct->buffer involves dereferencing simp_struct first and
    then accessing the structure component named buffer there, so
    simp_struct needs to be given a value first.

    > call_func((void **)((int **)(simp_struct->buffer)));
    > ....
    >}

    --
    Prototypes are supertypes of their clones. -- maplesoft
     
    Walter Roberson, Apr 21, 2006
    #3
  4. Twister said:

    <snip>

    > simp_struct->buffer = malloc(10 * sizeof(int *));
    >
    > call_func((void **)((int **)(simp_struct->buffer)));


    Why not just do this:

    call_func(&simp_struct->buffer);

    Casts are almost always wrong.


    > The function call_func has this prototype:
    > call_func(void **buf);
    >
    > I am confused with this piece of code:
    > call_func((void **)((int **)(simp_struct->buffer)));
    >
    > What does this construct mean?


    It means you don't (or whoever wrote it doesn't) understand what casting is
    for.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Apr 21, 2006
    #4
  5. Walter Roberson said:

    > In article <k872g.27$>,
    > Twister <> wrote:
    >
    >>struct simple{
    >> void *buffer;
    >>};
    >>typedef struct simple Simple;

    >
    >>void do_Something(){
    >>
    >> Simple *simp_struct;

    >
    > simp_struct is an uninitialized pointer after that statement.


    Good spot. I didn't see that. Silly me.

    Everything I said still applies, but that applies too!

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Apr 21, 2006
    #5
  6. Twister said:

    > for(i=0; i<10 ;i++)
    > call_func((void **)((int **)simp_struct->buffer + i));
    >
    > My question remains the same. What does the above
    > construct mean?


    That's a major difference.

    What you have now is a bug.

    simp_struct->buffer has type void *, so you can't do pointer arithmetic on
    it. So the cast to int ** gives you a value (of type int **) with which you
    /can/ do pointer arithmetic. That is, (int **)simp_struct->buffer + i gives
    you the address of the i'th int **, starting at simp_struct->buffer. The
    expression has type int **. The cast to void ** is an error because there
    is no guarantee that an int ** can be copied to a void ** without loss of
    information.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Apr 21, 2006
    #6
  7. Twister

    Twister Guest

    Richard Heathfield wrote:
    > Twister said:
    >
    >
    >>for(i=0; i<10 ;i++)
    >> call_func((void **)((int **)simp_struct->buffer + i));
    >>
    >>My question remains the same. What does the above
    >>construct mean?

    >
    >
    > That's a major difference.
    >
    > What you have now is a bug.
    >
    > simp_struct->buffer has type void *, so you can't do pointer arithmetic on
    > it. So the cast to int ** gives you a value (of type int **) with which you
    > /can/ do pointer arithmetic. That is, (int **)simp_struct->buffer + i gives
    > you the address of the i'th int **, starting at simp_struct->buffer. The
    > expression has type int **. The cast to void ** is an error because there
    > is no guarantee that an int ** can be copied to a void ** without loss of
    > information.
    >


    simp_struct->buffer was earlier initialized to point to memory
    of 10 (int *)'s. So isn't just saying, (int *)simp_struct->buffer + i
    correct? Why cast it to an (int **), unless i'm not passing it
    to a function which expects a int ** or a void ** ? Please correct
    me if i'm wrong here.

    Rgds.
    Mirage
     
    Twister, Apr 21, 2006
    #7
  8. Twister said:

    > Richard Heathfield wrote:
    >> Twister said:
    >>
    >>
    >>>for(i=0; i<10 ;i++)
    >>> call_func((void **)((int **)simp_struct->buffer + i));
    >>>
    >>>My question remains the same. What does the above
    >>>construct mean?

    >>
    >>
    >> That's a major difference.
    >>
    >> What you have now is a bug.
    >>
    >> simp_struct->buffer has type void *, so you can't do pointer arithmetic
    >> on it. So the cast to int ** gives you a value (of type int **) with
    >> which you /can/ do pointer arithmetic. That is, (int
    >> **)simp_struct->buffer + i gives you the address of the i'th int **,
    >> starting at simp_struct->buffer. The expression has type int **. The cast
    >> to void ** is an error because there is no guarantee that an int ** can
    >> be copied to a void ** without loss of information.
    >>

    >
    > simp_struct->buffer was earlier initialized to point to memory
    > of 10 (int *)'s. So isn't just saying, (int *)simp_struct->buffer + i
    > correct?


    No, that would point to the i'th int, not the i'th int *.

    > Why cast it to an (int **),


    To get a pointer to the i'th int *.

    > Please correct me if i'm wrong here.


    The cast to int ** is correct, but doesn't help you solve your void **
    problem.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Apr 21, 2006
    #8
  9. Twister

    Twister Guest

    Richard Heathfield wrote:
    > Twister said:
    >
    >
    >>Richard Heathfield wrote:
    >>
    >>>Twister said:
    >>>
    >>>
    >>>
    >>>>for(i=0; i<10 ;i++)
    >>>> call_func((void **)((int **)simp_struct->buffer + i));
    >>>>
    >>>>My question remains the same. What does the above
    >>>>construct mean?
    >>>
    >>>
    >>>That's a major difference.
    >>>
    >>>What you have now is a bug.
    >>>
    >>>simp_struct->buffer has type void *, so you can't do pointer arithmetic
    >>>on it. So the cast to int ** gives you a value (of type int **) with
    >>>which you /can/ do pointer arithmetic. That is, (int
    >>>**)simp_struct->buffer + i gives you the address of the i'th int **,
    >>>starting at simp_struct->buffer. The expression has type int **. The cast
    >>>to void ** is an error because there is no guarantee that an int ** can
    >>>be copied to a void ** without loss of information.
    >>>

    >>
    >>simp_struct->buffer was earlier initialized to point to memory
    >>of 10 (int *)'s. So isn't just saying, (int *)simp_struct->buffer + i
    >>correct?

    >
    >
    > No, that would point to the i'th int, not the i'th int *.
    >
    >
    >>Why cast it to an (int **),

    >
    >
    > To get a pointer to the i'th int *.
    >
    >
    >>Please correct me if i'm wrong here.

    >
    >
    > The cast to int ** is correct, but doesn't help you solve your void **
    > problem.
    >


    Thanks. That clarified part of my question.

    >The cast to void ** is an error because there is no guarantee that an
    >int ** can be copied to a void ** without loss of information.


    The malloc just allocated enough space for 10 (int *) pointers.
    The pointers themselves are not pointing to valid memory. So If I cast
    simp_struct->buffer finally to a void **(after the cast to an int **)
    and pass it to a function which allocates some momory and points these
    int *'s to valid memory, am I not doing the right thing ? Where is the
    loss of information happening ?

    Rgds.
    Mirage
     
    Twister, Apr 21, 2006
    #9
  10. Twister said:

    > Richard Heathfield wrote:
    >
    > >The cast to void ** is an error because there is no guarantee that an
    > >int ** can be copied to a void ** without loss of information.

    >
    > The malloc just allocated enough space for 10 (int *) pointers.


    Yes.

    > The pointers themselves are not pointing to valid memory.


    Right.

    > So If I cast
    > simp_struct->buffer finally to a void **(after the cast to an int **)
    > and pass it to a function which allocates some momory and points these
    > int *'s to valid memory, am I not doing the right thing ?


    No, I'm afraid not.

    > Where is the loss of information happening ?


    There's no guarantee that information is lost. There's just no guarantee
    that it's not lost! Either could happen. In other words, it might "work"
    just fine on your development machine - and then break on some other box.

    The problem is that, whilst the Standard guarantees that you can use void *
    to store any object pointer (without loss of information), it doesn't offer
    the same guarantee for void **.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Apr 21, 2006
    #10
  11. Twister

    Joe Smith Guest

    "Richard Heathfield" <> wrote in message
    news:...
    > Walter Roberson said:
    >
    >> In article <k872g.27$>,
    >> Twister <> wrote:
    >>
    >>>struct simple{
    >>> void *buffer;
    >>>};
    >>>typedef struct simple Simple;

    >>
    >>>void do_Something(){
    >>>
    >>> Simple *simp_struct;

    >>
    >> simp_struct is an uninitialized pointer after that statement.

    >
    > Good spot. I didn't see that. Silly me.
    >
    > Everything I said still applies, but that applies too!


    I've been looking for some common notions that I thought I had read in your
    book. I was hoping you might help me find them. Joe
    ----------
    C drifts
    and seems

    But now,
    I'm piffed
    and meeved

    and in a bad mood
     
    Joe Smith, Apr 30, 2006
    #11
  12. Joe Smith said:

    > I've been looking for some common notions that I thought I had read in
    > your
    > book. I was hoping you might help me find them. Joe


    I've been in RL for a few days, and I seem to have lost the plot here. If
    you could make it clearer what you're after, I'll be happy to do what I can
    to help you in your search.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Apr 30, 2006
    #12
  13. Twister

    CBFalconer Guest

    Richard Heathfield wrote:
    > Joe Smith said:
    >
    >> I've been looking for some common notions that I thought I had
    >> read in your book. I was hoping you might help me find them.

    >
    > I've been in RL for a few days, and I seem to have lost the plot
    > here. If you could make it clearer what you're after, I'll be
    > happy to do what I can to help you in your search.


    OT - what is an RL?

    --
    "Churchill and Bush can both be considered wartime leaders, just
    as Secretariat and Mr Ed were both horses." - James Rhodes.
    "We have always known that heedless self-interest was bad
    morals. We now know that it is bad economics" - FDR
     
    CBFalconer, Apr 30, 2006
    #13
  14. Twister

    ed Guest

    On Sun, 30 Apr 2006 08:16:56 -0400
    CBFalconer <> wrote:

    > OT - what is an RL?


    Real Life I think, the AP was talking about spending time away from the
    computer I believe.

    --
    Regards, Ed :: http://www.s5h.net
    :%s/Open Source/Free Software/g :: Free DNS available
     
    ed, Apr 30, 2006
    #14
  15. CBFalconer said:

    > Richard Heathfield wrote:
    >> Joe Smith said:
    >>
    >>> I've been looking for some common notions that I thought I had
    >>> read in your book. I was hoping you might help me find them.

    >>
    >> I've been in RL for a few days, and I seem to have lost the plot
    >> here. If you could make it clearer what you're after, I'll be
    >> happy to do what I can to help you in your search.

    >
    > OT - what is an RL?


    It's what happens to you when you pop into the Big Room for a while (the one
    with the really high grey-blue ceiling and imitation artificial light).

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Apr 30, 2006
    #15
  16. Twister

    Michael Mair Guest

    Richard Heathfield schrieb:
    > CBFalconer said:
    >>Richard Heathfield wrote:
    >>>Joe Smith said:
    >>>
    >>>
    >>>>I've been looking for some common notions that I thought I had
    >>>>read in your book. I was hoping you might help me find them.
    >>>
    >>>I've been in RL for a few days, and I seem to have lost the plot
    >>>here. If you could make it clearer what you're after, I'll be
    >>>happy to do what I can to help you in your search.

    >>
    >>OT - what is an RL?

    >
    > It's what happens to you when you pop into the Big Room for a while (the one
    > with the really high grey-blue ceiling and imitation artificial light).


    Oh, the one with the incredibly high resolution and artifact-free
    animation? I don't know, about half the time the sprinkler system or
    the air conditioning is defect. The worst thing, though, is that you
    cannot change the options.

    -Michael
    --
    E-Mail: Mine is an /at/ gmx /dot/ de address.
     
    Michael Mair, Apr 30, 2006
    #16
  17. Michael Mair said:

    > Richard Heathfield schrieb:
    >> CBFalconer said:
    >>>Richard Heathfield wrote:
    >>>>Joe Smith said:
    >>>>
    >>>>
    >>>>>I've been looking for some common notions that I thought I had
    >>>>>read in your book. I was hoping you might help me find them.
    >>>>
    >>>>I've been in RL for a few days, and I seem to have lost the plot
    >>>>here. If you could make it clearer what you're after, I'll be
    >>>>happy to do what I can to help you in your search.
    >>>
    >>>OT - what is an RL?

    >>
    >> It's what happens to you when you pop into the Big Room for a while (the
    >> one with the really high grey-blue ceiling and imitation artificial
    >> light).

    >
    > Oh, the one with the incredibly high resolution and artifact-free
    > animation? I don't know, about half the time the sprinkler system or
    > the air conditioning is defect. The worst thing, though, is that you
    > cannot change the options.


    A source (who wishes to remain anonymous!) has asked me, on the off-chance
    that the maintenance team read clc, to add that the thermostat is broken.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, Apr 30, 2006
    #17
  18. Twister

    Joe Smith Guest

    [funny stuff snipped]

    I've been writing elementary programs to knock some of the rust off my game
    here. Both Professors Knuth and Gallian start with Euclid's algortihm. I
    would like to implement it with the memory techniques at the beginning of
    _Unleashed_ Should I start clean with a new thread? I must say, while I
    didn't catch why a person would want cast a void * to void**, it doesn't
    sound like a very good idea. Joe
     
    Joe Smith, May 1, 2006
    #18
  19. Joe Smith said:

    > [funny stuff snipped]
    >
    > I've been writing elementary programs to knock some of the rust off my
    > game
    > here. Both Professors Knuth and Gallian start with Euclid's algortihm. I
    > would like to implement it with the memory techniques at the beginning of
    > _Unleashed_


    I'm not sure why you'd need memory techniques for Euclid's Algorithm.

    You can find an implementation on p326 of CU. Alternatively, here's my own,
    relatively straightforward, implementation of Knuth's description of
    Euclid's Algorithm in TAOCP:

    unsigned long gcd(unsigned long m, unsigned long n)
    {
    if(n == 0)
    {
    /* Caller doesn't know what he's doing. It's not
    * our job to bomb out, so we'll simply return an
    * impossible result - 0 - to match our impossible
    * input.
    */
    }
    else if(m < n)
    {
    n = gcd(n, m);
    }
    else
    {
    unsigned long r = m % n;
    if(r > 0)
    {
    n = gcd(n, r);
    }
    }
    return n;
    }


    > Should I start clean with a new thread? I must say, while I
    > didn't catch why a person would want cast a void * to void**, it doesn't
    > sound like a very good idea.


    I see no need for it, and you're right - it sounds like a bad idea. Not bad
    in itself, exactly, but it's a hint that someone, somewhere, is either
    assuming or just hoping(!) that void ** carries with it the same guarantees
    that void * does - but, alas, this is not the case.

    --
    Richard Heathfield
    "Usenet is a strange place" - dmr 29/7/1999
    http://www.cpax.org.uk
    email: rjh at above domain (but drop the www, obviously)
     
    Richard Heathfield, May 1, 2006
    #19
  20. Twister

    Joe Smith Guest

    "Richard Heathfield" opined:
    > Joe Smith said:
    >> I've been writing elementary programs to knock some of the rust off my
    >> game
    >> here. Both Professors Knuth and Gallian start with Euclid's algortihm.
    >> I
    >> would like to implement it with the memory techniques at the beginning of
    >> _Unleashed_

    >
    > I'm not sure why you'd need memory techniques for Euclid's Algorithm.
    >
    > You can find an implementation on p326 of CU. Alternatively, here's my
    > own,
    > relatively straightforward, implementation of Knuth's description of
    > Euclid's Algorithm in TAOCP:
    >
    > unsigned long gcd(unsigned long m, unsigned long n)
    > {
    > if(n == 0)
    > {
    > /* Caller doesn't know what he's doing. It's not
    > * our job to bomb out, so we'll simply return an
    > * impossible result - 0 - to match our impossible
    > * input.
    > */
    > }
    > else if(m < n)
    > {
    > n = gcd(n, m);
    > }
    > else
    > {
    > unsigned long r = m % n;
    > if(r > 0)
    > {
    > n = gcd(n, r);
    > }
    > }
    > return n;
    > }
    >
    >
    >> Should I start clean with a new thread? I must say, while I
    >> didn't catch why a person would want cast a void * to void**, it doesn't
    >> sound like a very good idea.

    >
    > I see no need for it, and you're right - it sounds like a bad idea. Not
    > bad
    > in itself, exactly, but it's a hint that someone, somewhere, is either
    > assuming or just hoping(!) that void ** carries with it the same
    > guarantees
    > that void * does - but, alas, this is not the case.


    'void**' reminds me of the Escher drawing of the hand drawing the hand and
    the peculiar way Goedel regarded his. I'll fire up that source you posted
    when I begin my campaign tomorrow to Take Over the Week. My methods for
    handling memory are childish. I think what I'll try to do is take the
    eratosthenos algorithm down yonder and have the user tell the prog how large
    an N we have. Joe
    ---------
    My hat usually has 3 corners but tonight has none.
     
    Joe Smith, May 1, 2006
    #20
    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. Ollej Reemt
    Replies:
    7
    Views:
    605
    Jack Klein
    Apr 22, 2005
  2. Stig Brautaset

    `void **' revisited: void *pop(void **root)

    Stig Brautaset, Oct 25, 2003, in forum: C Programming
    Replies:
    15
    Views:
    840
    The Real OS/2 Guy
    Oct 28, 2003
  3. David M. Wilson
    Replies:
    8
    Views:
    505
    Ben Pfaff
    Jan 7, 2004
  4. Enrico `Trippo' Porreca

    Casting const void * into void *

    Enrico `Trippo' Porreca, May 31, 2004, in forum: C Programming
    Replies:
    14
    Views:
    991
    August Derleth
    Jun 4, 2004
  5. Replies:
    5
    Views:
    886
    S.Tobias
    Jul 22, 2005
Loading...

Share This Page