Unexpected sign extension of int32 or 32bit pointer when converted to uint64

前端 未结 4 1993
醉话见心
醉话见心 2020-12-19 19:50

I compiled this code using Visual Studio 2010 (cl.exe /W4) as a C file:

int main( int argc, char *argv[] )
{
    unsigned __int64 a = 0x00000000         


        
相关标签:
4条回答
  • 2020-12-19 20:24

    Use this to avoid the sign extension:

    unsigned __int64 a = 0x00000000FFFFFFFFLL;
    

    Note the L on the end. Without this it is interpreted as a 32-bit signed number (-1) and then cast.

    0 讨论(0)
  • 2020-12-19 20:30

    Converting a pointer to/from an integer is implementation defined.

    Here is how gcc does it, i.e. it sign extends if the integer type is larger than the pointer type(this'll happen regardless of the integer being signed or unsigned, just because that's how gcc decided to implement it).

    Presumably msvc behaves similar. Edit, the closest thing I can find on MSDN is this/this, suggesting that converting 32 bit pointers to 64 bit also sign extends.

    0 讨论(0)
  • 2020-12-19 20:39

    Integer constants (e.g, 0x00000000FFFFFFFF) are signed integers by default, and hence may experience sign extension when assigned to a 64-bit variable. Try replacing the value on line 3 with:

    0x00000000FFFFFFFFULL
    
    0 讨论(0)
  • 2020-12-19 20:45

    From the C99 standard (§6.3.2.3/6):

    Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type.

    So you'll need to find your compiler's documentation that talks about that.

    0 讨论(0)
提交回复
热议问题