C ++ combining to represent data memory with variable type variable C

Today I have a strange question.

Code (C ++)

#include <iostream> union name { int num; float num2; }oblong; int main(void) { oblong.num2 = 27.881; std::cout << oblong.num << std::endl; return 0; } 

Code (C)

 #include <stdio.h> int main(void) { float num = 27.881; printf("%d\n" , num); return 0; } 

Question

  • As you know, C ++ associations can contain more than one type of data elements, but only one type at a time. So basically name oblong reserve only one piece of memory, which is 32-bit (since the largest type in the union is 32-bit, int and float), and this part may contain integers or float.

  • So I just assign the value 27.881 to oblong.num2 (as you can see in the above code). But out of curiosity, I turn to memory using oblong.num , which points to the same place in memory.

  • As expected, this gave me a value that is not equal to 27, since the float and integer method presented inside the memory is different, so when I use oblong.num to access a part of the memory, it will treat this part of the memory value as a whole and interpret it using the integer representation method.

  • I know this phenomenon will also happen in C, so I initialize a variable of type float with a value, and then read it with %d . So just try using this value of 27.881 , which you can see above. But when I run it, something strange happens, that is, the value of the one I get in C is different from C ++.

  • Why is this happening? From what I know, the two values ​​that I get from the two codes, after all, are not garbage values, but why do I get different values? I also use sizeof to check both the C and C ++ integer and the size of the float, and both are 32-bit. So the memory size is not the one that makes this happen, so tell me this difference in values?

+6
source share
2 answers

First of all, the wrong printf() format string is undefined behavior. Now that it’s said, here’s what actually happens in your case:

In vararg functions such as printf() , integers smaller than int move up to int , and floats smaller than double move up to double .

As a result, your 27.881 converted to an 8-byte double, as it is passed to printf() . Therefore, the binary representation no longer matches the float .

The format string %d expects a 4-byte integer. This way you will print the bottom 4 bytes of the view with a double precision of 27.881 . (assuming little-endian)

* Actually (subject to strict FP) you see the bottom 4 bytes of 27.881 after it was added to the float , and then it moves to double .

+9
source

In both cases, you encounter undefined behavior. Your implementation just does something weird.

+2
source

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


All Articles