Home > Blockchain >  Union value in C
Union value in C

Time:08-16

Can somebody explain to me what happens with br agument in union, after assigning str.a and str.b? We need to set that value before calling the function above? I tried to run the code in simulator https://pythontutor.com/render.html#mode=display which says that the value of br is 516 before calling the function. How is that possible?

 #include <stdio.h>
void f(short num, short* res){
 if (num){
 *res = *res * 10   num;
 f(num / 10, res);
}}


typedef union {
 short br;
 struct {
 char a, b;
 } str;
} un;

void main() {
 short res = 0; un x;
 x.str.a = 4; x.str.b = 2;
 f(x.br, &res); x.br = res;
 printf("%d %d %d\n", x.br, x.str.a, x.str.b);}

CodePudding user response:

The value of the short will depend on the computer's endianess. On a little endian machine, a will correspond to the least significant byte and b to the most significant. Thus when those two bytes are converted to a short, you get the number 0x0204 = 516 decimal.

As a side note, it is a bad idea to use short and char since those may be signed and negative. Use uint16_t and uint8_t instead, whenever dealing with binary arithmetic.

CodePudding user response:

Assuming that char is one byte and short is two bytes (the most common), then it's really simple.

Begin by drawing out the members of the union on a piece of paper, one member next to the other. Something like this:

 br      str
 ---     --- 
|   |   |   | a
 ---     --- 
|   |   |   | b
 ---     --- 

Now we do the assignments:

x.str.a = 4;
x.str.b = 2;

And write the results in the drawing:

 br      str
 ---     --- 
| 4 |   | 4 | a
 ---     --- 
| 2 |   | 2 | b
 ---     --- 

Assuming little endianness like on a normal x86 or x86-64 system, then the value of br will be 0x0204 which is 516 in decimal.

So that's where the value 516 is coming from.

CodePudding user response:

If you put some effort into your debugging you would see what is going on:

void f(short num, short* res)
{
    if (num)
    {
        *res = *res * 10   num;
        f(num / 10, res);
    }
}


typedef union 
{
    short br;
    struct 
    {
        char a, b;
    };
} un;

int main(void) 
{
    short res = 0; un x;
    x.a = 4; x.b = 2;
    printf("Before br=0xx (%d) a=0xx b=0xx res = %d 0x%x\n", x.br, x.br, x.a, x.b, res, res);
    f(x.br, &res); x.br = res;
    printf("After  br=0xx a=0xx b=0xx res = %d 0x%x\n", x.br, x.a, x.b, res, res);
}

result:

efore br=0x0204 (516) a=0x04 b=0x02 res = 0 0x0
After  br=0x0267 a=0x67 b=0x02 res = 615 0x267

Do your br was 516 and it was reversed by the f function becoming 615 which is 0x0276. It contains of two bytes 0x02 and 0x67.

Your computer is little-endian so the first byte is 0x67 and the second one is 0x02 because this system stores the least significant byte first.

  • Related