I came across this quiz, so want to verify it myself:
#include <stdio.h>
void
print_sum(a, b)
{
printf("%d\n", a + b);
}
int
main(void)
{
print_sum(1.5, 8.5);
return 0;
}
I used https://godbolt.org/ to test it:
(1) Use x86-64 clang (trunk) with -std=c89 option, the result is 9;
(2) But x86-64 gcc (trunk) with -std=c89 option, the result is 158013177.
From my understanding, the default type of a and b should be int, so the 1.5 should be converted to 1 and 8.5 converted to 8 when passing to print_sum(). But obviously gcc doesn't follow it.
So I am just wondering under c89, is this a gcc bug or the above program has "undefined behaviour?
The program has undefined behavior.
This:
is an "old-style" declaration. It makes
aandbparameters of typeint, but it doesn't communicate that information to any callers.This call:
since the visible declaration is not a prototype for the function, causes the compiler to assume that the called function takes two arguments of type
double. The arguments are not converted fromdoubletoint. They're simply passed asdouble, and the function assumes that it's been given twointarguments. The different behavior might be the result of different calling conventions (unlikely since gcc and clang should be compatible), or different optimizations.The fix is to change the declaration to a prototype, i.e., a declaration that specifies the types of its arguments. Change this:
to this: