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?
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?
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.
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");
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.