What mistake I am doing here in C code

Thread Starter

aamirali

Joined Feb 2, 2012
412
I wrote following code


Rich (BB code):
typedef union
{
    struct
    {
        int8_t   a;
        int16_t  b;
        uint32_t c;
    };

    int8_t my_arr[7];
}x;

uint8_t arr[7];

int main( void )
{
    uint32_t i;
    x *y;

    for( i = 0 ; i < 7 ; i++ )
    {
        arr = i + 2 * 5;
    }

    y = ( x* )arr;

    i = y->a;
    i = y->b;
    i = y->c;
}




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
 

YokoTsuno

Joined Jan 1, 2013
45
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.
 

WBahn

Joined Mar 31, 2012
33,120
I wrote following code


Rich (BB code):
typedef union
{
    struct
    {
        int8_t   a;
        int16_t  b;
        uint32_t c;
    };

    int8_t my_arr[7];
}x;

uint8_t arr[7];

int main( void )
{
    uint32_t i;
    x *y;

    for( i = 0 ; i < 7 ; i++ )
    {
        arr = i + 2 * 5;
    }

    y = ( x* )arr;

    i = y->a;
    i = y->b;
    i = y->c;
}




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


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.
 

codehead

Joined Nov 28, 2011
57
Rich (BB code):
typedef union
{
    struct
    {
        int8_t   a;
        int16_t  b;
        uint32_t c;
    };

    int8_t my_arr[7];
}x;
End result in Y is:
a = 0x0a;
b = 0x0d0c
c = 0x00100F0E
my_arr[0-7] = 0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,0x10;
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.
 
Top