0
#include <stdio.h>
union p{
int x;
char y;
};
int main(){
union p a;
a.y = 60;
a.x = 12;
printf("%f ",a.y);
printf("%d ",a.y);
printf("%d",a.x);
}

In above output is 0.000000 and 12 and 12 but i think it must be 12 and 12 and 12 can someone explain.

  • 6
    Why would you expect `%f` to print anything reasonable? It doesn't match either of the types in your union, and in any case, there's no mechanism which could possibly perform the necessary conversion. – Steve Summit Aug 27 '19 at 17:54
  • 1
    See also [this answer](https://stackoverflow.com/questions/7480097/what-happens-to-a-float-variable-when-d-is-used-in-a-printf/57645470#57645470) to a [similar question](https://stackoverflow.com/questions/7480097). – Steve Summit Aug 27 '19 at 17:57
  • 3
    `a.y = 60; a.x = 12;` is contradictory. In a `union` it can't be both. A `union` is not a `struct`. – Weather Vane Aug 27 '19 at 18:01
  • Also, when you put 12 into `.x` and pull a char value out of `.y`, it's not guaranteed to be 12, either (that is, not even if you print it with `%d`, it's just not even guaranteed to be the char value 12 at all). – Steve Summit Aug 27 '19 at 18:02
  • .. only if little-endian. – Weather Vane Aug 27 '19 at 18:04

1 Answers1

1

a.y is a char but here

printf("%f ",a.y);

you print it as if it is a double. That is undefined behaviour, i.e. you can get any kind of output.

Always use the correct format specifier.

Make sure to observe compiler warnings! For gcc I get

main.cpp: In function 'main':
main.cpp:12:10: warning: format '%f' expects argument of type 'double', but argument 2 has type 'int' [-Wformat=]
   12 | printf("%f ",a.y);
      |         ~^   ~~~
      |          |    |
      |          |    int
      |          double
      |         %d

which tells that something is all wrong.

If you change the code to

#include <stdio.h>
union p{
    int x;
    char y;
    float z;
};

int main(){
    union p a;
    a.y = 60;
    a.x = 12;
    printf("%.200f ",a.z);
    printf("%d ",a.y);
    printf("%d",a.x);
}

the code becomes valid C code and gives this result:

0.00000000000000000000000000000000000000000001681558157189780485108475499947899357536314330251818926108481940667749299223032721783965826034545898437500000000000000000000000000000000000000000000000000000 12 12

on most little endian machines.

Support Ukraine
  • 42,271
  • 4
  • 38
  • 63