Retrieve an integer from the byte buffers read from the socket is implementation-defined?

Viewed 71

Consider we have a sequence of bytes whose value representation like the following

00000000, 00000000, 00000001, 00000000

It designates the integer value 256 on machine A, which is encoded by big-endian. Assume the destination machine is little-endian. Now, we have common functions like that

unsigned long octets_to_unsigned32_little_endian(unsigned char *p)
{
  return p[0] | 
    ((unsigned)p[1]<<8) |
    ((unsigned long)p[2]<<16) |
    ((unsigned long)p[3]<<24);
}
/* long octets_to_signed32_little_endian(unsigned char *p)
{
  unsigned long as_unsigned = octets_to_unsigned32_little_endian(p);
  if (as_unsigned < 0x80000000)
    return as_unsigned;
  else
    return (long)(as_unsigned^0x80000000UL)-0x40000000L-0x40000000L;
} */

However, [basic.types.general] p4 says

For trivially copyable types, the value representation is a set of bits in the object representation that determines a value, which is one discrete element of an implementation-defined set of values.

In the above example, regardless of how we retrieve the integer from the buffers, it always depends on how the value representation of the integer is. In other words, the implementation of the above functions always assumes the value representation of the integer value in the destination machine is 00000000 00000001 00000000 00000000. In other words, the implementation can consider the value representation of the value 256 to be 00000000 10000000 00000000 0000000, or 00000000 11111111 10101010 0000000, or anyway, which does not violate the requirement of the standard.

Two questions

  1. Retrieve an integer from the byte buffers is implementation-defined?
  2. Is there any way that can get rid of implementation-defined?
1 Answers

You're not really doing operations on the value representation. You're not casting encoded values or anything.

You're doing mathematics.

p[1]<<8 is a math operation, mathematically equivalent to multiplying the numerical value at p[1] by the decimal value "256". Math defines the result of that operation.

Similarly, doing a bitwise | operation is mathematics. You take the two numbers represented in binary, and perform a bitwise "or" on them, which results in a new binary value. Math defines the result of that operation too.

The value representation only matters to the extent that the result of the math can be completely encoded in that value representation. The value representation is where you get the numbers from, and where the numbers go to, but what happens in the middle is just doing math on numbers.

Related