What mistake I am doing here in C code

Discussion in 'Programmer's Corner' started by aamirali, Jun 8, 2013.

  1. aamirali

    Thread Starter Member

    Feb 2, 2012
    I wrote following code

    Code ( (Unknown Language)):
    1. typedef union
    2. {
    3.     struct
    4.     {
    5.         int8_t   a;
    6.         int16_t  b;
    7.         uint32_t c;
    8.     };
    10.     int8_t my_arr[7];
    11. }x;
    13. uint8_t arr[7];
    15. int main( void )
    16. {
    17.     uint32_t i;
    18.     x *y;
    20.     for( i = 0 ; i < 7 ; i++ )
    21.     {
    22.         arr[i] = i + 2 * 5;
    23.     }
    25.     y = ( x* )arr;
    27.     i = y->a;
    28.     i = y->b;
    29.     i = y->c;
    30. }[/i]

    End result in Y is:
    a = 0x0a;
    b = 0x0d0c
    c = 0x00100F0E
    my_arr[0-7] = 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10;

    & array conatisn
    arr[0-7] = 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10;

    My question is when a= 0x0a , then should be b = 0x0c0b & c = 0x100f0e0d
    but this is not the case

    I am using keil, mdk arm
  2. YokoTsuno


    Jan 1, 2013
    This is obviously related to the Endianess of your platform.


    If the storage order of variables which require more then a single byte (Uint16, 32) is not in the same order, the method of retrieval you use is not so simple.

    I also don't understand the role of the UINT8 array in the union. x stores a pointer and not an entire array in your case. To me this seems obsolete, unless this has a future purpose.
  3. WBahn


    Mar 31, 2012

    This is REALLY odd code. I'm assuming it is just something thrown together to tinker with unions and such, which is fine.

    I have no idea what a "conatisn" is or means or refers to. Please clarify.

    The problem that you are having is that the C compiler has the flexibility, within constraints, to position elements of a structure in order to align the elements. Thus, the structure is allocated as follows:


    Do a sizeof(x) and you will probably find that it is 8 and not 7.

    To play with this some more, do the following:

    typedef struct {double d, uint8_t c, int32_t i} d_c_i;
    typedef struct {uint8_t c, double d, int32_t i} c_d_i;

    now print out sizeof(d_c_i) and sizeof(c_d_i).

    I haven't tried this, so I might be wrong, but my guess is that you will find that

    sizeof(d_c_i) = 16
    sizeof(c_d_i) = 24

    Let us know what you get.
  4. codehead

    Active Member

    Nov 28, 2011
    That's because the compiler doesn't put the int16_t b starting at my_arr[1]. It uses a pad byte to even-align, and puts b at my_arr[2]. You always need to pay attention to struct alignment when you're doing this sort of thing. Aligning multibyte values on odd addresses is usually a performance hit for processors.