-4

I am reading the C book K&R. I know that the macro EOF on my system is -1.

int eof = EOF;
printf("EOF on my system is: %d\n",eof);

But when I assign EOF to a union, the output somehow confused me. I can only understand v.ival is -1. Anyone can explain why the rest of them: v.cval, v.fval, and v.dval would be like this?

union eof_val {
    int ival;
    char cval;
    float fval;
    double dval;
} eof;

eof.ival = EOF;

printf("EOF to int = %d\n", eof.ival);        /* output: -1 */
printf("EOF to char = %c\n", eof.cval);       /* output: � */
printf("EOF to float = %f\n", eof.fval);      /* output: nan */
printf("EOF to double = %f\n", eof.dval);     /* output: 0.000000 */
dbush
  • 205,898
  • 23
  • 218
  • 273
shen
  • 933
  • 10
  • 19
  • 1
    reading `dval` results in undefined behavior because `int` is probably shorter than `double` – phuclv Jul 26 '17 at 03:07
  • @LưuVĩnhPhúc okey. but how to explain `cval`? `-1` in `int` occupies 4 bytes `0xFF 0xFF 0xFF 0xFF` in memory. thus `cval` should equals to `0xFF` right? which is `255` on ascii table? – shen Jul 26 '17 at 03:24
  • 2
    undefined behavior means *anything can happen*, including [making demons fly out of your nose](http://www.catb.org/jargon/html/N/nasal-demons.html). However in this case the character at code point 255 is printed out. `%c` is not for printing a char as its numeric value. Use `printf("%d\n", (char)eof.cval)` instead – phuclv Jul 26 '17 at 03:32
  • for sure it will not print 255, but the 255th character in ascii table. `0xFF` is the value on memory. am I right? – shen Jul 26 '17 at 03:40
  • 1
    "a test, to have a look in memory." --> instead add member `unsigned char uc[sizeof double]` and print the elements of the array in hex to gain a better understanding. – chux - Reinstate Monica Jul 26 '17 at 03:51
  • good hint! thx @chux :> – shen Jul 26 '17 at 04:12
  • @LưuVĩnhPhúc output for `printf("%d\n", (char)eof.cval)` is not `255` as expected, but still `-1`... – shen Jul 26 '17 at 04:22
  • 1
    @weiShen it's because [`char` is signed by default on your platform](https://stackoverflow.com/q/2054939/995714). Change to `unsigned char` and see – phuclv Jul 26 '17 at 04:42
  • @LưuVĩnhPhúc finally got `255`. thank you for your patience :) – shen Jul 26 '17 at 05:07

1 Answers1

1

A union is big enough to hold the biggest of it's members. It does not hold them all. Only one of it's values is usable at a time.

You've set ival and it's good, but that means cval, fval and dval pretty much hold rubbish (not quite: you could figure it out based on the value of ival)

Not a duplicate, but interesting reading: Why do we need C Unions?

John3136
  • 28,809
  • 4
  • 51
  • 69