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
    415
    1
    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.     };
    9.  
    10.     int8_t my_arr[7];
    11. }x;
    12.  
    13. uint8_t arr[7];
    14.  
    15. int main( void )
    16. {
    17.     uint32_t i;
    18.     x *y;
    19.  
    20.     for( i = 0 ; i < 7 ; i++ )
    21.     {
    22.         arr[i] = i + 2 * 5;
    23.     }
    24.  
    25.     y = ( x* )arr;
    26.  
    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 4.70.0.0, mdk arm
     
  2. YokoTsuno

    Member

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

    http://en.wikipedia.org/wiki/Endianness

    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

    Moderator

    Mar 31, 2012
    17,777
    4,805


    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:

    [aa,xx,bb,bb,cc,cc,cc,cc]

    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

    Member

    Nov 28, 2011
    56
    11
    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.
     
Loading...