compare void* with uint16_t

540 Views Asked by At

In some legacy code, which compiles fine on GCC 4.6 (with -fpermissive), I have this:

uint16_t a = 0;
void* b = ...;

if(b == a) // ...

Is this comparison well-defined on GCC 4.6? Does it downcast to 16 bits or upcast to 32/64 bits?

3

There are 3 best solutions below

2
On BEST ANSWER

Looks like it up-casts the 16 bit integer to match the pointer size. Running the following code outputs "upcast"

uint16_t a = 1;
void* b = (void*)0x10001;
(b == a) ? printf("downcast") : printf("upcast");
3
On

Although this isn't explicitly written in the C++11 standard (N3337 draft), I was able to come up with this (emphasis mine).

§5.9 Relational operators

Pointers to objects or functions of the same type (after pointer conversions) can be compared, with a result defined as follows

— If two pointers ...

— If two pointers ...

— If two pointers ...

— If two pointers ...

— If two pointers ...

Other pointer comparisons are unspecified.

Now for the equality part:

§5.10 Equality operators

The == (equal to) and the != (not equal to) operators have the same semantic restrictions, conversions, and result type as the relational operators except for their lower precedence and truth-value result.

By this I believe that such a comparison is unspecified.

0
On

It may compile or may not (not sure, it depends on the compiler and compiler options) In any case the cast will be performed like:

if( b == (void*)a )
{
}

Note that upcasting/downcasting is not the correct word to use because it is related to classes, in this case is just type conversions.