Does cast between signed and unsigned int maintain exact bit pattern of variable in memory?

前端 未结 3 857
佛祖请我去吃肉
佛祖请我去吃肉 2020-12-13 04:41

I want to pass a 32-bit signed integer x through a socket. In order that the receiver knows which byte order to expect, I am calling htonl(x) befor

3条回答
  •  不思量自难忘°
    2020-12-13 05:04

    In general, casting in C is specified in terms of values, not bit patterns - the former will be preserved (if possible), but the latter not necessarily so. In case of two's complement representations without padding - which is mandatory for the fixed-with integer types - this distinction does not matter and the cast will indeed be a noop.

    But even if the conversion from signed to unsigned would have changed the bit pattern, converting it back again would have restored the original value - with the caveat that out-of-range unsigned to signed conversion is implementation-defined and may raise a signal on overflow.

    For full portability (which will probably be overkill), you'll need to use type punning instead of conversion. This can be done in one of two ways:

    Via pointer casts, ie

    uint32_t u = *(uint32_t*)&x;
    

    which you should be careful with as it may violate effective typing rules (but is fine for signed/unsigned variants of integer types) or via unions, ie

    uint32_t u = ((union { int32_t i; uint32_t u; }){ .i = x }).u;
    

    which can also be used to eg convert from double to uint64_t, which you may not do with pointer casts if you want to avoid undefined behaviour.

提交回复
热议问题