Thread: compare void pointer

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

    compare void pointer

    I face an issue in my c++ program
    when I try to compare an integer variable with a variable void*

    It keeps returning the errors:

    error C2446: '==' : no conversion from 'void *' to 'int'
    error C2040: '==' : 'int' differs in levels of indirection from 'void *'

    I understand there's a problem but how that can be fixed?
    Is there some sort of casting?

    Code:
    int price;
    void* val;
    
    if(price==val)
    //do things

  2. #2
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Why would you want to do that ?

    Still, you could use a reinterpret_cast
    Code:
    if(price==reinterpret_cast<int>(val))
    Kurt

  3. #3
    Registered User
    Join Date
    May 2011
    Posts
    116
    Quote Originally Posted by ZuK View Post
    Why would you want to do that ?

    Still, you could use a reinterpret_cast
    Code:
    if(price==reinterpret_cast<int>(val))
    Kurt
    I have to check every time if void* val is either an integer or a char*..
    For char* though it returns no mistakes

  4. #4
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Quote Originally Posted by quo View Post
    I have to check every time if void* val is either an integer or a char*..
    You cannot check that. A void * points to a value of unknown type. You have to know what it points to to cast it to the right type.
    Kurt

  5. #5
    Registered User
    Join Date
    May 2011
    Posts
    116
    Quote Originally Posted by ZuK View Post
    You cannot check that. A void * points to a value of unknown type. You have to know what it points to to cast it to the right type.
    Kurt
    yes you're right,but when I know that it's a char* and I have to compare it to another char* it doesn't return error message as it did with int.
    So I guess there's no casting needed when I know it's char*.Right?
    Or am I missing something here??

  6. #6
    Algorithm Dissector iMalc's Avatar
    Join Date
    Dec 2005
    Location
    New Zealand
    Posts
    6,318
    Generally in C++, void* is not used. In C++ the normal way to deal with things that can be of several types is to either use templates, or a type safe variant kind of structure.
    You might use void* if you have to interact with a C API, but other than that it's pretty rare.

    Comparing char* to void* is less likely to be a problem as far as the compiler is concerned because they are both the same level of indirection.
    However an int is not a pointer, and it could very well be that rather than convert the pointer to an int, the API you're using might actually be giving you a pointer to an int, in which case you'd need to typecast to an int* and then dereference it.
    The compiler is right to complain.
    My homepage
    Advice: Take only as directed - If symptoms persist, please see your debugger

    Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"

  7. #7
    Registered User
    Join Date
    May 2011
    Posts
    116
    Quote Originally Posted by iMalc View Post
    Generally in C++, void* is not used. In C++ the normal way to deal with things that can be of several types is to either use templates, or a type safe variant kind of structure.
    You might use void* if you have to interact with a C API, but other than that it's pretty rare.

    Comparing char* to void* is less likely to be a problem as far as the compiler is concerned because they are both the same level of indirection.
    However an int is not a pointer, and it could very well be that rather than convert the pointer to an int, the API you're using might actually be giving you a pointer to an int, in which case you'd need to typecast to an int* and then dereference it.
    The compiler is right to complain.
    yes actually it interacts with C.That's why I need it.
    For the integer I did what I was told to do in the previous posts:

    Code:
    if(price==reinterpret_cast<int>(val))
    and now the compiler doesn't complain.
    On the other hand for the char* I simply did:

    Code:
    if(price==val)
    and the compiler didn't return any error so I figured no change is needed here.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    You do need, however, to question why you need to do such comparisons in the first place.

    In both C and C++, a conversion of any pointer type (such as char *) to a void pointer (void *) is implicit - the compiler will do the conversion, without being told to, and without complaining. In C, the reverse (implicit conversion of a void * to a char *) is also permitted - this is not permitted in C++.

    A comparison of a void * with a char * is permitted indirectly: the char * is implicitly converted to a void *, and then the two void pointers are compared. If you know the void * is actually a char *, all is fine. If it is an integral value (or if it is a pointer to some type other than char) the comparison yields undefined behaviour.

    It is possible to force the issue by an explicit type conversion (such as a reinterpret_cast) but such tricks are often not a good idea.

    In your case, shutting up the compiler is the least significant part of your problem - and, apparently, the only problem you are accounting for.

    The other problem - which you have not addressed - is ensuring that the value in the pointer was an integer in the first place. Otherwise, the code will exhibit undefined behaviour. For example;
    Code:
       void *val = reinterpret_cast<void *>(42);
    
        if (42 == reinterpret_cast<int>(val))
    or, equivalently, if you are passing void pointers as arguments to functions
    Code:
    void *callback(void *val)
    {
          if (42 == reinterpret_cast<int>(val)) whatever();
    }
    
    //  and to call it
    
    int main()
    {
       callback(reinterpret_cast<void *>(42));
    }
    The problem is that both of these code fragments do a round-trip conversion (convert an int (42) to void * and back again). Such round-trip conversions are not guaranteed to work (which is why the compiler complains on at least one of the conversions, unless you bludgeon it into submission with an explicit type conversion). Formally, once you have bludgeoned the compiler into submission, the code actually exhibits undefined behaviour. Informally, if a void * is larger than an int are the same size, there is a chance that the value 42 will survive the round-trip conversion. The problem is that there are real-world compilers that support an int larger than a void * - the round-trip conversion does not work with such compilers.

    Generally, if you are going to use any explicit type conversions (a C-style cast or, in C++, the _cast operators) you need to do some analysis akin to my examples above, and pick a compiler appropriately, to ensure validity of your code.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  9. #9
    Registered User
    Join Date
    May 2011
    Posts
    116
    thank you all so much for your answers!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. compare pointer and integer?
    By nyekknyakk in forum C Programming
    Replies: 19
    Last Post: 08-19-2010, 10:19 PM
  2. Replies: 4
    Last Post: 08-27-2007, 11:51 PM
  3. compare pointer to int without new var
    By avgprogamerjoe in forum C++ Programming
    Replies: 5
    Last Post: 08-25-2007, 11:59 PM
  4. Dereference pointer to void pointer to member
    By phil in forum C Programming
    Replies: 5
    Last Post: 04-20-2005, 11:54 AM
  5. Replies: 5
    Last Post: 10-29-2001, 10:16 AM