Types of cast pointers on different architectures

I have the following structure and the getter function, which returns a conversion 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 executed:

 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 compared to big-endian?

+6
source share
1 answer

The problem is that you have:

 uint16_t x; 

but then you try to write to this memory location, as if it were an unsigned place.

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

First of all, it causes undefined behavior, violating the rule of strict aliases . Variables of type uint16_t can only be written via lvalues ​​of type uint16_t or character type.

But even if this does not violate a strict alias, you will still call UB, writing outside x . Perhaps you are writing 4 or 8 bytes in a 2-byte memory location, so it will overflow the buffer.

It may also be UB if x is incorrectly aligned for unsigned .

+5
source

All Articles