0

i'm currently working on a Port of Embedded Code (on a Freescale S12) so GNU and i hava a issue with unions. i have the following union

typedef signed short        sint16;
typedef signed long         sint32;

typedef union
{
    sint32 Akku;
    sint16 AkkuHigh;
    sint16 AkkuLow;
} akku_type;

and i want to access the highest 2 byte of the union. The Problem is, that both AkkuHigh and AkkuLow have the same starting adress as Akku. It seems to be compiler specific. My Questions are: Is the there a Compiler Flag which changes the behaviour of the union? Can atribute((align (2))) help me?

Thank you in Advance

timrau
  • 22,578
  • 4
  • 51
  • 64
  • Pack the `high` and `low` fields in an inner anonymous `struct`. Strictly speaking it's not portable, but it should work. – user703016 Dec 03 '14 at 17:44
  • 1
    Why did you expect them to have different addresses? – Borgleader Dec 03 '14 at 17:45
  • @ParkYoung-Bae: C allows it, and it's a common C++ extension. Wonder why the committee didn't cave in and legitimize it... – Deduplicator Dec 03 '14 at 17:50
  • @ParkYoung-Bae: Padding at the *beginning* of a struct? Where did you get that standards-breaking compiler? (And non-neccessary padding *after* a member is just weird, and not yet found in the wild.) – Deduplicator Dec 03 '14 at 17:55

2 Answers2

3

Yes, all of Akku, AkkuHigh, AkkuLow have the same address. This is how unions work in C. By the look of it, you intended to make an union with a 32-bit member and a member that is a struct of two 16-bit members instead. What you wrote is not the way to achieve it. Try instead:

typedef union
{
    sint32 Akku;
    struct s {
      sint16 AkkuHigh;
      sint16 AkkuLow;
    } representation;
} akku_type;
Pascal Cuoq
  • 79,187
  • 7
  • 161
  • 281
  • Is it guaranteed that `AkkuHigh` will be the high byte and `AkkuLow` will be the low byte? Couldn't the compiler decide to switch them around? – Unapiedra Dec 03 '14 at 17:45
  • @Unapiedra The guarantee is that the addresses of the members of a struct are in order. What these addresses correspond to is implementation-dependant (typically, this depends on the endianness of the target architecture. The struct as written works for most big-endian architectures). – Pascal Cuoq Dec 03 '14 at 17:48
  • @Unapiedra: Switching them around is not allowed, but adding arbitrary (implementation-defined) amounts of padding after `struct`-members is (*not* before them). – Deduplicator Dec 03 '14 at 17:57
0

The correct definition of the union can be found in this answer.

atribute(align(2)) will definitely help you if you compile this on a 32bit or 64bit architecture. Also, on 64bit sizeof(sint32) is 8 (64 bits).

Depending on the endian-ness of the architecture, you may need to swap AkkuHigh and AkkuLow.

Community
  • 1
  • 1
axiac
  • 68,258
  • 9
  • 99
  • 134