Casting pointer types on different architectures
Asked Answered
F

1

6

I have the following structure and "getter" function that returns a cast to an unsigned integer:

struct s {
    uint32_t a;
};

void get_a(struct s *st, unsigned *ret)
{
    *ret = (unsigned)st->a;
}

The following code is run:

struct s st;
uint16_t x;

st.a = 1;
get_a(&st, (unsigned *)&x);

And for x86_64, i686, armv7hl, ppc64le and other architectures x == 1, but for ppc64 x == 0. Why is this? Little- vs. big-endian?

Foilsman answered 24/7, 2015 at 10:1 Comment(1)
Set a to 0x12345678. Little-endian machines will return 0x5678, big-endian 0x1234. To maintain same behavior on all machines use htonl/htons/ntohl/ntohs functions.Pomeroy
H
5

The problem is that you have:

uint16_t x;

but then you try to write to that memory location as if it were the location of unsigned.

If you were on a system where unsigned and uint16_t are the same type, this is fine. But on other systems, such as the one you used for your code sample, you are in trouble.

First of all, this causes undefined behaviour by violating the strict aliasing rule. Variables of type uint16_t may only be written to through lvalues of type uint16_t, or a character type.

But even if it did not violate strict aliasing, you would still cause UB by writing outside the bounds of x. Probably, you are writing 4 or 8 bytes into a 2-byte memory location, so it will overflow the buffer.

There could also be UB if x is not correctly aligned for unsigned.

Homogeneous answered 24/7, 2015 at 10:9 Comment(3)
I think it's also worth mentioning that endianness has nothing to do in this case.Shimmy
@black it sort of does: if all of the UB in the code doesn't produce nasal demons this time, we might expect that the 1 bit being written appears either inside x or outside x depending on the system endiannessHomogeneous
Lesson learned: Do not cast pointers, or at least be very careful with what you are doing. There mostly ever is a different solution. Here a temporary unsigned typed variable would have wiped away all uncertainties.Oporto

© 2022 - 2024 — McMap. All rights reserved.