When the first edition of K&R was written, there was no C standard. When the second edition of K&R was written, the C89/C90 standard was about to be finalized. Because of the legacy from code written before C89 was finalized, the standard had to permit:
#include <stdio.h>
double sqrt();
main(argc, argv)
char **argv;
{
if (argc > 1)
printf("sqrt(%s) = %f\n", argv[1], sqrt((double)atoi(argv[1])));
else
printf("sqrt(%.0f) = %f\n", 2.0, sqrt(2.0));
return 0;
}
Note that the return type of main()
is implicitly int
; the function argument argc
is implicitly int
; the function atoi()
has an implicit return type of int
. Note too that the argument to sqrt()
had to be explicitly a double value; the compiler could not automatically convert the argument type because prototypes were not a part of C before the C89 standard.
Such code is no longer acceptable to C99 or C11 compilers. You could use:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv)
{
if (argc > 1)
printf("sqrt(%s) = %f\n", argv[1], sqrt(atoi(argv[1])));
else
printf("sqrt(%.0f) = %f\n", 2.0, sqrt(2));
return 0;
}
This uses the standard headers to declare the functions with complete prototypes, so it is no longer necessary to cast the argument to sqrt()
. In C99 or C11, you could omit the return 0;
and the effect would be the same. Personally, I don't like the loophole that allows that and continue to write the return explicitly. The return was necessary in C90 to send a determinate status to the environment (e.g. the shell the invoked the program).