Array orientation in structure

To declare a union below

union a { int i; char ch[2]; }; union au; u.ch[0] = 3; u.ch[1] = 2; 

Since i and ch are stored in the same place, i should now be <binary rep. of 3> <binary rep. of 3> connected to <binary rep. of 2> <binary rep. of 2> . However, it is saved in reverse order.

 printf("%d",i); 

gives 515. Why so?

+4
source share
3 answers

The result depends on the endianness of the machine on which you are trying to enable your program.

515 on a small Intel i686 end machine:

 $ uname -m i686 $ ./a.out 515 

and 770 on a bin endian machine such as Sparc:

 $ uname -m sun4v $ ./a.out 770 

This is because endianess will determine whether ch[0] a higher order byte (in bytes) or a low byte (at the small end) i .

+2
source

Because you type %d , which is for a number. So you have:

 u.ch[0] = 3; 

which is in binary format

 0000 0011 // 8bits, as char is 1B 

then you have

 u.ch[1] = 2; 

which the

 0000 0010 // 8bits, as char is 1B 

And "when you put 2 and 2 together" (: D)

  00..00 0000 0010 0000 0011 // sizeof (int) * 8 bits ^^^^^^ ^^^^^^^^^ ^^^^^^^^^ //(sizeof(int)*8-16)bits this is the 2 this is the 3 

which is 515 in dec.


Sorry, I missed the why part. It depends on the platform, you should read about Endianness and, more specifically, about big endians and little-endian. There are several examples in this article. Hint: it seems that you have a car with small ends.

Well, I will summarize my comment here: arrays are guaranteed to be stored in continuous memory. Assume sizeof( int ) == 2 , for a simpler explanation . So you have

 u.ch[0] = 3; u.ch[1] = 2; 

At first 3 will be saved, and on the next byte 2 will be recorded. SO, how do you (I think) expect memory:

 0000 0011 0000 0010 ^^^^3^^^^ ^^^^2^^^^ 

BUT remember that you are using union ! And you type int . SO, this int has the same bit:

 0000 0011 0000 0010 

And your cars are little oriented, which translates this:

 0000 0010 0000 0011 (reversed order of the bytes!) 

What is the binary representation of 515

+3
source

He gives 515 because this is unspecified behavior. No one can answer your question without knowing which compiler you are using and how this compiler handles unions.

  • The compiler can store any number of padding bytes within your union, with the exception of the very first byte.

  • The program is required only to return the result corresponding to the last access of the union. If your access was through an element of the char array, then only read access to the char array will be guaranteed. Reading an int member can give you anything; you may not know that.

  • Since this is undefined behavior, the compiler does not even need to document how it will handle such calls. If you're lucky, they did it.

  • This is great for the compiler to give you fill bytes or garbage values ​​for code like this.

0
source

Source: https://habr.com/ru/post/1382847/


All Articles