-2

So I have the following code:

uint32_t length = 1;
uint8_t buffer[5];

buffer[0] = htonl(length);

std::cout << (uint32_t)*buffer << std::endl;
std::cout << htonl(length) << std::endl;

The second to last line prints out 0, the last line prints out 16777216.....why....?

ldav1s
  • 15,885
  • 2
  • 53
  • 56
Ethan
  • 1,206
  • 3
  • 21
  • 39

2 Answers2

3

You are not actually putting the uint32_t in the array of uint8_ts. Instead, you are placing it in buffer[0]. Since length is much larger, only the lowest 8 byte will be stored. And since you've called htonl(length), the lowest 8 bytes are actually all 0 (at least if your host system is using a different byte-order than the network - and this seems to be the case here).

If you actually want to use the first four elements of buffer to be used to store length, you have to tell the compiler to re-interpret them as a uint32_t.

uint32_t length = 1;
uint8_t buffer[5];

(uint32_t&)*buffer = htonl(length);

std::cout << (uint32_t)*buffer << std::endl;
std::cout << htonl(length) << std::endl;

Not that it's a good idea to do, though ..

s3rius
  • 1,442
  • 1
  • 14
  • 26
  • It's always been my understanding that in C you can do things like this. It will simply spill over to the rest of the array....however I am compiling with C++. Is the C++ the difference? – Ethan Dec 10 '13 at 00:48
  • 1
    It would be the same in C. If you wrote `int i = 10000000000UL` the compiler would "cut" the value down to size to store it inside. Assignments like that will never spill over into other memory. With the `(uint32_t&)` I'm telling the compiler to treat the memory area that `buffer` points to like a `uint32_t` and thus it'll be able to store the value without cutting it down. – s3rius Dec 10 '13 at 00:50
-1

The second to last line prints out zero coincidentally -- you never stored anything in buffer. You set buffer[0] to a value that wouldn't fit there and left the rest uninitialized.

The last line prints out 16,777,216 because your platform is little-endian and htonl switches to big-endian format, so your 0,0,0,1 becomes 1,0,0,0. That's a one in the 256^3 place, and 1 * 256^3 = 16,777,216.

David Schwartz
  • 179,497
  • 17
  • 214
  • 278
  • The first paragraph isn't true. He stored in `buffer[0]` and in the `cout` he dereferenced `buffer` which gives him the first element of the array. It prints 0 because he called `htol()` which switches around byte order and causes the lower 8 bytes (which are copied into `buffer[0]`) to be 0. – s3rius Dec 10 '13 at 00:54