Prior to the 1989 ANSI C standard, the only way to define a function in C did not specify the number and types of any parameters. (This old version of the language is called "K&R C", since it's described in the first edition of The C Programming Language by Kernighan and Ritchie.) You're using an old-style function definition:
void func(a)
{
printf("%d\n", a);
}
Here a
is the name of the parameter. It is implicitly of type int
, but that information is not used in determining the correctness of a call to func
.
C89 added prototypes, which allow you to specify the types of parameters in a way that is checked when the compiler sees a call to the function:
void func(int a)
{
printf("%d\n", a);
}
So in the 1989 version of the C language, your program is legal (in the sense that there are no errors that need to be diagnosed at compile time), but its behavior is undefined. func
will probably grab whatever value happens to be in the location in which it expects the caller to place the value of the argument. Since no argument was passed, that value will be garbage. But the program could in principle do literally anything.
The 1999 version of the language dropped the "implicit int
" rule, so a
is no longer assumed to be of type int
even with the old-style definition.
But even the latest 2011 version of C hasn't dropped old-style function definitions and declarations. But they've been officially obsolescent since 1989.
Bottom line: Always use prototypes. Old-style function definitions and declarations are still legal, but there is never (or very rarely) any good reason to use them. Unfortunately your compiler won't necessarily warn you if you use them accidentally.
(You're also using an old-style definition for main
. int main()
is better written as int main(void)
. This is less problematic than it is for other functions, since main
is not normally called, but it's still a good habit.)