Thread: Working with void pointers

  1. #1
    Registered User
    Join Date
    May 2011
    Posts
    68

    Working with void pointers

    I have a struct
    Code:
    typedef struct 
    {  
        void *l_var;      
        void *r_var;    
    }EXPR;
    
    EXPR expr;
    I initialize it
    Code:
    expr.l_var = &motor_rt_params[0].position;
    expr.r_var = &motor_rt_params[1].position;
    Now I want to operate with the values
    Code:
    result = *(expr.l_var) – *( expr.r_var);
    I get an exception
    Error[Pe041]: expression must have arithmetic or pointer type

    I have to cast it to a known type
    Code:
    result = *((int32_t *) expr.l_var) - *((int32_t *)expr.r_var);
    But not all variables is 32 bit? there is 16, 8 bit.
    How can cast it to an appropriate type in run time?

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by john7
    But not all variables is 32 bit? there is 16, 8 bit.
    How can cast it to an appropriate type in run time?
    You would cast to a pointer to whatever is the underlying type, in this case it would be the type of &motor_rt_params[0].position. It is also always safe to cast to a pointer to a character type to compute the difference in bytes, but is that what you're trying to do here?

    By the way, I don't recommend EXPR as a struct alias. It is common convention in C for fully uppercase names to be used for macros or constants. A capitalised name like Expr might be a suitable alternative.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    Programming Wraith GReaper's Avatar
    Join Date
    Apr 2009
    Location
    Greece
    Posts
    2,738
    You cast it to whatever pointer type it should be. I don't understand your problem, did you think you could only cast it to a single type?
    Devoted my life to programming...

  4. #4
    Registered User
    Join Date
    May 2011
    Posts
    68
    Quote Originally Posted by laserlight View Post
    You would cast to a pointer to whatever is the underlying type, in this case it would be the type of &motor_rt_params[0].position. It is also always safe to cast to a pointer to a character type to compute the difference in bytes, but is that what you're trying to do here?

    By the way, I don't recommend EXPR as a struct alias. It is common convention in C for fully uppercase names to be used for macros or constants. A capitalised name like Expr might be a suitable alternative.
    But how I decide what type to cast? It is generic function
    Code:
    void SCRIPT_Process(void *l_var, void *r_var, uint32_t oper)
    {
        int32_t res;
        
        switch (oper)
        {
            case OP_PLUS: 
                res = *((??? *) l_var) + *((??? *)r_var);
            break;
            case OP_MINUS: 
                res = *((??? *) l_var) - *((??? *)r_var);
            break; 
        }
    }
    How can I know what type the argument points and what type to cast?
    Code:
    SCRIPT_Process(expr.l_var , expr.r_var , OP_PLUS);
    Last edited by john7; 05-12-2019 at 04:19 AM.

  5. #5
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    One approach is to do something similiar to the standard qsort function: have a function pointer parameter, and hence offload the casting and relevant operation to a function specified by the caller. Another approach is to introduce a macro such that the type for the cast can be a macro argument, hence when the macro is used, the appropriate type can be provided.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  6. #6
    Registered User
    Join Date
    May 2011
    Posts
    68
    Quote Originally Posted by laserlight View Post
    One approach is to do something similiar to the standard qsort function: have a function pointer parameter, and hence offload the casting and relevant operation to a function specified by the caller. Another approach is to introduce a macro such that the type for the cast can be a macro argument, hence when the macro is used, the appropriate type can be provided.
    sorry. I missed to understand. how can I do it practically? the only way I see - to add some variable
    type_size = sizeof(my_current_var);
    and according to a type_size do some cast in SCRIPT_Process.
    Last edited by john7; 05-12-2019 at 04:35 AM.

  7. #7
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by GReaper View Post
    You cast it to whatever pointer type it should be. I don't understand your problem, did you think you could only cast it to a single type?
    If I undestand correctly your question, it is why you have to cast a void pointer to a specific type pointer, isn't it?

    If you think about the pointer variable as a container of a memory address, when you use the indirection operator * you are reading/writing a bunch of bytes in/from memory - void pointers are generic pointers (they can point to any type), when using * to read/write data pointed, the compiler doesn't know how many bytes it should deal with:
    Code:
     int x;
    void *p = &x;
    
    // How many bytes to write to the address
    // given by p? 1, 2, 4, 8?
    *p = 0;
    
    *(int *)p = 0; // ahh... write 4 bytes (sizeof(int) bytes)!

  8. #8
    Registered User
    Join Date
    May 2011
    Posts
    68
    Quote Originally Posted by flp1969 View Post
    If I undestand correctly your question, it is why you have to cast a void pointer to a specific type pointer, isn't it?
    No! Let me simplify for better understanding.
    Code:
    switch (type)
     {
            case TYPE_u8:
                *(uint8_t*)res = *(uint8_t*)l + *(uint8_t*)r;
                break;
            case TYPE_u16:
                *(uint16_t*)res = *(uint16_t*)l + *(uint16_t*)r;
                break;
            case TYPE_u32:
                *(uint32_t*)res = *(uint32_t*)l + *(uint32_t*)r;
                break;
            default:
                assert(0);
     }
    but I pass a void* (generic) argument. How can I know it's type (TYPE_u8, TYPE_u16, TYPE_u32) ?

  9. #9
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078
    Quote Originally Posted by john7 View Post
    No! Let me simplify for better understanding.
    Code:
    switch (type)
     {
            case TYPE_u8:
                *(uint8_t*)res = *(uint8_t*)l + *(uint8_t*)r;
                break;
            case TYPE_u16:
                *(uint16_t*)res = *(uint16_t*)l + *(uint16_t*)r;
                break;
            case TYPE_u32:
                *(uint32_t*)res = *(uint32_t*)l + *(uint32_t*)r;
                break;
            default:
                assert(0);
     }
    but I pass a void* (generic) argument. How can I know it's type (TYPE_u8, TYPE_u16, TYPE_u32) ?
    If you have a void pointer, you can't... (void *) is a wildcard, but it doesn't carry any type information with it...

  10. #10
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    You could add a "type" field to your "EXPR" structure and then pass that to the "SCRIPT_Process" function to determine the type.

  11. #11
    Registered User
    Join Date
    May 2011
    Posts
    68
    Quote Originally Posted by christop View Post
    You could add a "type" field to your "EXPR" structure and then pass that to the "SCRIPT_Process" function to determine the type.
    Yes. The only way. I was trying to avoid it cause it inflates my struct (it's actually an array of struct) and it consumes a lot of space, so I'm struggling for every byte.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Void Function not working.. : / (noob coder)
    By Jonathan002 in forum C++ Programming
    Replies: 2
    Last Post: 10-26-2013, 03:12 AM
  2. working with void ** (NOOB)
    By MishaMish in forum C++ Programming
    Replies: 1
    Last Post: 01-18-2011, 05:11 PM
  3. working with void pointers
    By Delia in forum C Programming
    Replies: 6
    Last Post: 03-30-2010, 11:45 PM
  4. Working with void*
    By Blackroot in forum C++ Programming
    Replies: 2
    Last Post: 03-21-2009, 09:51 AM
  5. working with void stars???
    By scarlet00014 in forum C Programming
    Replies: 13
    Last Post: 10-25-2008, 10:41 AM

Tags for this Thread