assigning void * type value

Discussion in 'C Programming' started by LordHog@hotmail.com, Apr 26, 2005.

  1. Guest

    Hello all,

    I am having a little problem getting my (void *) assignment to work
    correctly. Basically it is some code for a circular queue buffer I am
    trying to implement, but getting the deferrencing of the (void *) type
    is giving me problems... For brevity sake not all the functions are
    defined, but the name gives a clue to what it does...


    [------------Code Begins------------]
    #define FAIL 0x01
    #define SUCCESS 0x00
    typedef unsigned long UINT32;

    typedef struct {
    void* data[CBQ_MAX_QUEUE_SIZE];
    INT8 head,
    tail;
    } CIRCULAR_BUF_DESCRIPTOR;


    STATUS_RESULT_TYPE PopCbq( CIRCULAR_BUF_DESCRIPTOR* QueueDescriptor,
    void* objectRef )
    {
    UINT32 test;
    UINT32* testRef;

    // Check for valid arguments
    if ( QueueDescriptor == NULLPTR || objectRef == NULLPTR ) { return
    FAIL; }

    // Check to make sure the queue isn't empty first.
    if ( IsCbqEmpty(QueueDescriptor) ) { return FAIL; }

    test = 0x5555;

    testRef = &test;

    *testRef = (void *)QueueDescriptor->data[QueueDescriptor->tail++];

    // The following line is where I am having the problems... I can get
    // the above line to work, but not this one... I am having
    indirection
    // problems, accoding to Visual C++ v6
    *objectRef = (void)QueueDescriptor->data[QueueDescriptor->tail++];

    // *objectRef = ((void *)test);

    return SUCCESS;
    }
    [------------Code Ends------------]


    So I am not sure what I am doing wrong.. I have tried various
    declarations, but none of them work. What am I doing wrong or might be
    a better approach? This function is suppose to take care or different
    types of data which the application later needs to cast it to the
    appropriate data type. Thanks for any help...

    Mark
    , Apr 26, 2005
    #1
    1. Advertising

  2. wrote:
    > Hello all,
    >
    > I am having a little problem getting my (void *) assignment to work
    > correctly.


    Don't cast the right operand of the assignment. The whole purpose
    of void * is that you _don't_ need to cast it when assigning to
    a compatible pointer type. e.g....

    T *p = malloc(N * sizeof *p);

    > Basically it is some code for a circular queue buffer I am
    > trying to implement, but getting the deferrencing of the (void *)

    type
    > is giving me problems... For brevity sake not all the functions are
    > defined, but the name gives a clue to what it does...
    > ...
    > STATUS_RESULT_TYPE PopCbq( CIRCULAR_BUF_DESCRIPTOR* QueueDescriptor,
    > void* objectRef

    )
    > {
    > UINT32 test;
    > UINT32* testRef;
    >
    > // Check for valid arguments
    > if ( QueueDescriptor == NULLPTR || objectRef == NULLPTR ) { return
    > FAIL; }
    >
    > // Check to make sure the queue isn't empty first.
    > if ( IsCbqEmpty(QueueDescriptor) ) { return FAIL; }
    >
    > test = 0x5555;
    >
    > testRef = &test;
    >
    > *testRef = (void *)QueueDescriptor->data[QueueDescriptor->tail++];


    Since testRef is a pointer to an integer, *testRef is an integer
    (lvalue). But you try to assign a void pointer, which is an
    incompatible type, indeed the code is a constraint violation.

    I'm surprise compilation doesn't stop at this line.

    > // The following line is where I am having the problems... I can

    get
    > // the above line to work, but not this one... I am having
    > indirection
    > // problems, accoding to Visual C++ v6
    > *objectRef = (void)QueueDescriptor->data[QueueDescriptor->tail++];


    You can't assign void objects.

    >
    > // *objectRef = ((void *)test);
    >
    > return SUCCESS;
    > }


    --
    Peter
    Peter Nilsson, Apr 26, 2005
    #2
    1. Advertising

  3. Guest

    Peter,

    Thanks for the very quick reply, but I am still unclear what I need
    to do in order to fix the code. After looking at the post I left
    testing code that wasn't suppose to be include, I am very sorry for
    this. All the code that uses the following

    UINT32 test;
    UINT32* testRef;

    isn't part of my original problem with trying trying to pop data out
    of array (void* data[CBQ_MAX_QUEUE_SIZE] ) and copy it into the input
    argument (void* objectRef) of the function
    PopCbq().

    Since the project that I am working on is embedded there is no use of
    dynamic allocation and everything is statically defined or locally
    defined within a function. I am not sure if that helps any, but just
    some back ground info.

    Mark
    , Apr 26, 2005
    #3
  4. On Mon, 25 Apr 2005 23:24:39 -0700, LordHog wrote:

    > Hello all,
    >
    > I am having a little problem getting my (void *) assignment to work
    > correctly. Basically it is some code for a circular queue buffer I am
    > trying to implement, but getting the deferrencing of the (void *) type
    > is giving me problems... For brevity sake not all the functions are
    > defined, but the name gives a clue to what it does...
    >
    >
    > [------------Code Begins------------]
    > #define FAIL 0x01
    > #define SUCCESS 0x00
    > typedef unsigned long UINT32;
    >
    > typedef struct {
    > void* data[CBQ_MAX_QUEUE_SIZE];
    > INT8 head,
    > tail;
    > } CIRCULAR_BUF_DESCRIPTOR;
    >
    >
    > STATUS_RESULT_TYPE PopCbq( CIRCULAR_BUF_DESCRIPTOR* QueueDescriptor,
    > void* objectRef )


    You need to explain what it is this function is supposed to be doing, and
    in particular what is the purpose of the objectRef argument

    > {
    > UINT32 test;
    > UINT32* testRef;
    >
    > // Check for valid arguments
    > if ( QueueDescriptor == NULLPTR || objectRef == NULLPTR ) { return
    > FAIL; }
    >
    > // Check to make sure the queue isn't empty first. if (
    > IsCbqEmpty(QueueDescriptor) ) { return FAIL; }
    >
    > test = 0x5555;
    >
    > testRef = &test;
    >
    > *testRef = (void *)QueueDescriptor->data[QueueDescriptor->tail++];
    >
    > // The following line is where I am having the problems... I can get
    > // the above line to work, but not this one... I am having
    > indirection
    > // problems, accoding to Visual C++ v6 *objectRef =
    > (void)QueueDescriptor->data[QueueDescriptor->tail++];
    >
    > // *objectRef = ((void *)test);


    It appears that you are trying to return in some way an entry that was in
    the datastructure indicated by QueueDescriptor. There are various ways you
    can go about this, e.g. return a pointer to the object in the
    datastructure or make a copy of the object.

    If you want to return a pointer then do that, the easiest way is to make
    the return type void * and use some other nethod to return a result code.
    You may just be able to return NULL to indicate failure. It is then the
    responsibility of the caller to convert the void * pointer to a pointer of
    the appropriate type and then use it. You could pass an argument of type
    void ** and write a void * value through that, but it is again the
    responsibility of the caller to convert the void * value to the correct
    type.

    If you want to make a copy of the object then you can have the caller
    define the destination object and pass a pointer to that for objectRef. It
    will also need to pass the size of the object as another argument because
    PopCbq just has a void * pointer i.e. it knows nothing about the object
    other than its start address in memory. So if you had

    STATUS_RESULT_TYPE PopCbq( CIRCULAR_BUF_DESCRIPTOR* QueueDescriptor,
    void* objectRef
    size_t objectSize)

    you might have something like

    memcpy(objectRef, QueueDescriptor->data[QueueDescriptor->tail++],
    objectsize);


    > return SUCCESS;
    > }
    > [------------Code Ends------------]
    >
    >
    > So I am not sure what I am doing wrong.. I have tried various
    > declarations, but none of them work. What am I doing wrong or might be a
    > better approach? This function is suppose to take care or different
    > types of data which the application later needs to cast it to the
    > appropriate data type. Thanks for any help...


    You first need to be clear about what it is you are trying to do. And be
    aware that there is no polymorphism in C, you can't access an object
    through a void * pointer to it, you have to convert the pointer back to an
    appropriate type in the code first. You CAN treat any object as an array
    of unsigned char if you know its size which is in effect what the memcpy()
    call above does.

    Lawrence
    Lawrence Kirby, Apr 26, 2005
    #4
  5. Old Wolf Guest

    wrote:
    >
    > ... my original problem with trying trying to pop data out
    > of array (void* data[CBQ_MAX_QUEUE_SIZE] ) and copy it into the

    input
    > argument (void* objectRef) of the function
    > PopCbq().


    C passes parameters by value. You are passing 'objectRef' as a
    parameter to a function. This means that the calling function must
    pass in a valid pointer to something, and the caller cannot see
    any changes that the function makes to 'objectRef'.

    If you are trying to return a value via a parameter, then the
    parameter needs to be a pointer to what you are trying to
    return.

    Here's a simple example:
    void get_int(int *p) { *p = 5; }
    void foo(void) { int x; get_int(&x); }

    Now to repeat the example but with (void *) as the type instead
    of int:

    STATUS_RESULT_TYPE PopCbq(
    CIRCULAR_BUF_DESCRIPTOR *QueueDescriptor,
    void **objectRef )
    {
    *objectRef = QueueDescriptor->data[QueueDescriptor->tail++];
    return 0;
    }

    void foo()
    {
    CIRCULAR_BUF_DESCRIPTOR bar;
    ...............
    void *ptr;
    PopCbq(&bar, &ptr);
    }

    You can then go on to use 'ptr' for whatever purpose (including
    converting it back to point to the type it was pointing to
    originally).
    Old Wolf, Apr 27, 2005
    #5
    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:
    499
    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:
    775
    The Real OS/2 Guy
    Oct 28, 2003
  3. Replies:
    5
    Views:
    815
    S.Tobias
    Jul 22, 2005
  4. Abhishek
    Replies:
    12
    Views:
    787
    Eric Sosman
    Jan 30, 2006
  5. Replies:
    1
    Views:
    392
    Victor Bazarov
    May 23, 2007
Loading...

Share This Page