-3

In Kernighan and Ritchie's C book, Im asked to write a program to print the value of EOF

I did it right by writing:

#include <stdio.h>
void main(){
    printf("%d", EOF);
}

I got it right by getting -1 as the answer...but out of curiosity I typed %f instead of %d. It's displaying 0.00000000

Why is that?

I got what I expected...but the latter (printing in float type), I did it out of curiosity, and thought the result should be -1.0 or something like that.

mousetail
  • 7,009
  • 4
  • 25
  • 45
  • 1
    Mismatching format specifier and argument type leads to *undefined behavior*. The `%f` format expects a `double` value, while `EOF` is an `int` value. – Some programmer dude Jul 14 '23 at 12:28
  • 1
    to print if as float you need to explicitly convert it to float `printf("%f", (double)EOF);` – 0___________ Jul 14 '23 at 12:30
  • negative `1` interpreted as a int is NaN, interesting that it prints `0` instead of `nan` like you would expect – mousetail Jul 14 '23 at 12:33
  • For different application binary interfaces (ABIs), parameters may be passed on the stack and/or in registers. And the registers used may depend on the type of the parameter. For example, floating point parameters may be passed in different registers to integer or pointer parameters. – Ian Abbott Jul 14 '23 at 12:36
  • @mousetail Because `%f` expects a `double` which is usually 64 bits, while `int` is typically 32 bits. Which means that there's 32 bits or garbage data being passed. Also the actual result will depend on the endianness of the system. – Some programmer dude Jul 14 '23 at 12:38
  • See also https://stackoverflow.com/questions/57859857/what-is-the-calling-convention-for-floating-point-values-in-c-for-x86-64-in-syst to get an explanation for what the program may do (But it is still UB, so don't relay on it). – 12431234123412341234123 Jul 14 '23 at 12:39
  • 4
    @Someprogrammerdude AMD64, which the OP most likely uses, uses different registers for floating point parameters than integers. – 12431234123412341234123 Jul 14 '23 at 12:40
  • 1
    OT: Return type of `main()` should be `int` not `void`. Enable compiler warnings (probably `-Wall -Wextra`). – 12431234123412341234123 Jul 14 '23 at 12:42
  • 1
    All arguments of calls to `printf` except the first argument containing the format string are *variadlc* arguments and will be passed using the *default argument promotion rules*. (`printf` is declared `int printf(const char *restrict format, ...);`. The `, ...` is a placeholder for zero or more *variadic* arguments.) `printf` uses the format string to decide how may variadic arguments it is expecting and their types. If the actual number of variadic arguments or their types are not as expected, that will result in *undefined behavior*. – Ian Abbott Jul 14 '23 at 12:44
  • 1
    @Someprogrammerdude Yes, you can test it with `printf("%f\n", 1, 1234.5678);`. – 12431234123412341234123 Jul 14 '23 at 13:03

1 Answers1

1

If the parameter of the printf does not match the format you invoke the Undefined Behaviour (UB).

You need to convert it to the double before passing to the printf function:

printf("%f", (double)EOF);
0___________
  • 60,014
  • 4
  • 34
  • 74