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
This should always be safe, because the intXX_t types are guaranteed to be in two's complement if they exist:
7.20.1.1 Exact-width integer types The typedef name intN_t designates a signed integer type with width N , no padding bits, and a two’s complement representation. Thus, int8_t denotes such a signed integer type with a width of exactly 8 bits.
Theoretically, the back-conversion from uint32_t to int32_t is implementation defined, as for all unsigned to signed conversions. But I can't much imagine that a platform would do differently than what you expect.
If you want to be really sure of this you still could to that conversion manually. You'd just have to test a value for > INT32_MAX and then do a little bit of math. Even if you do that systematically, a decent compiler should be able to detect that and optimize it out.