-4
static int i = 2;
union U {
  int a, b;
  char c[3];
}u;


 int main(){
   u.b = 0x6;
   for(;i; u.b++)
    u.b = u.a << i--;
  printf("%d %o %s", u.a, u.b, u.c);
 return 0;
}

This code gives the output for the character array as 3. Now I know that this code poses several Undefined Behaviour specially when I am a storing into one variable and accessing of some other, but just for the purpose of experiment, can anybody explain to me why u.c has a value of 3.

Note: Internal memory structure would be better to understand this

Mayukh Sarkar
  • 2,289
  • 1
  • 14
  • 38

3 Answers3

1

After the for loop the union u contains the bits:

0x00000033

which split into chars are

0x33 0x00 0x00

so

c[0]=0x33
c[1]=0x00
c[2]=0x00

and 0x33 happens to be the ASCII code for the digit '3';

Lorenzo Belli
  • 1,767
  • 4
  • 25
  • 46
0

You can symply test it printing the hex code of a with:

printf("\n%X\n", u.a);

Output will be 0x33, that is ASCII 3

The for loop do

  • Start with b=0x06
  • Then left shift by 2 => b=0x18
  • Inc b => b= 0x19
  • Then left shift b by 1 => b=0x32
  • Inc b => b= 0x33

You define an union then a coincide with b. First 3 byte of a and b are also accessible by c.

BTW printf output depends on endianess of data.

In your case, Little Endian, printf print ASCII 3, because of c is:

c[0]=0x33
c[1]=0x00
c[2]=0x00

In case of Big Endian printf print nothing, because of c is:

c[0]=0x00
c[1]=0x00
c[2]=0x00
LPs
  • 16,045
  • 8
  • 30
  • 61
0

u.a, u.b and c's bytes all occupy the same memory. Since u.a. and u.b have the same type they are essentially the same variable. The loop

int i=2;
u.b = 6;
for(;i; u.b++)
    u.b = u.a << i--;

can be written (just using u.b for clarity) as:

u.b = 6;

u.b = u.b << 2;  // u.b is now 24 (one bit shift left is multiplying by 2)
u.b++;           // u.b is now 25

u.b = u.b << 1; // u.b is now 50
u.b++;          // u.b is now 51.

Now the memory layout of a 32 bit integer on a PC with low byte first is, byte wise, 51-00-00-00.

Interpreting these bytes as a string, as you told printf to do with the %s conversion, means that 51 is taken as an ascii value, denoting the letter 3. Fortunately the next byte is indeed 0, because the integer is small, so that the string is terminated. printf will print 3.

Peter - Reinstate Monica
  • 15,048
  • 4
  • 37
  • 62