-4

Why does this code prints nonsense values? If it makes sense then what is it?

printf("%d\n", 5.0 / 4);

By the way, I know about format specifiers I should be using %f instead of %d. but I want to know what c actually does.

Strangely, every time I run the compiled program, it prints a different thing. doesn't it have to be deterministic?

As far as I could observe, this code prints a similar thing:

float c;
printf("%d\n", &c);

are they any related?

and when i tried:

float c;
printf("%d\n%d\n", c, &c);

There is a constant 252 between those two values. 256 - sizeof(float) maybe? and declaring c as a double makes the difference 0.

Thanks in advance!

UPDATE: writing the same code on different machines yielded different results.(252 being 56. former is a 64-bit ubuntu machine and latter is 64-bit OS X)

Koopakiller
  • 2,838
  • 3
  • 32
  • 47
D. Jones
  • 461
  • 2
  • 16
  • Your code has undefined behaviour. – Kerrek SB Mar 09 '16 at 18:44
  • And it is pretty useless to try and *investigate* UD - Your implementation can do anything or nothing. It is like investigating nonsense. – tofro Mar 09 '16 at 18:51
  • @tofro Nevertheless, many textbooks -- including the venerable K&R -- invite readers to experiment and see what happens. The lesson is supposed to be that the behavior is strange and random, so you shouldn't depend on it. Unfortunately some programmers try to learn what behavior they happen to get under one particular compiler on one particular day, and then try to depend on it later. – Steve Summit Mar 09 '16 at 19:10
  • Multi-dup. Duped so many times I've lost count:( – Martin James Mar 09 '16 at 19:10
  • http://meta.stackoverflow.com/questions/318526/how-should-we-deal-with-c-language-questions-that-operate-outside-of-the-realm – Martin James Mar 09 '16 at 19:11

1 Answers1

0

printf is unusual in that it has no single function signature. In other words, there's no mechanism to automatically take the actual arguments you pass and convert them into the type that's expected. Whatever you try to pass, gets passed. If the type you pass does not match the type expected by the corresponding format specifier, you get nonsense.

Furthermore, if the mismatched types you're passing versus what the format specifiers are expecting have different sizes, printf can end up popping random garbage off the stack, that has nothing to do with what you thought you passed.

You asked, "doesn't it have to be deterministic?", and the answer there is a very emphatic "NO"! By passing the wrong type of value to printf, you have invoked undefined behavior, which means that anything can happen, and it very definitely does not have to be the same thing twice.

(Even though they're not required to, some compilers peek at the format string and try to check the values you passed against the values that are expected. For example, under gcc, your first code fragment gets the warning "format ‘%d’ expects type ‘int’, but argument 2 has type ‘double’". But I don't know of a compiler that will try to do conversions to "fix" the arguments.)

Steve Summit
  • 45,437
  • 7
  • 70
  • 103