I've read some, to me, peculiar C-code while studying some examples in the book The Unix Programming Environment (1983).
As a curiosity I wanted to find out more about the, let's call it "style". The point of interest here is the line just below int main(argc, argv)
#include <stdio.h>
int main(argc, argv)
char *argv[];
{
printf("%s\n", argv[0]);
return 0;
}
In my investigation I've found that compiling the above code with the flags -Wall -pedantic -ansi
works without any warnings, and replacing -ansi
with the more recent -std=c99
(or c11
, with gcc
and cc
) only warns about argc
defaulting to int
.
I perused the old C89 standard trying to find references to this particular way of writing but didn't find anything on my own so I defer to the greater knowledge of the collective.
Hence the question, from when does this esoteric writing stem and possibly why is it still allowed (legacy reasons?)
The old way to do things was to have functions without prototypes. Functions return int
by default, and since the function parameter types are unknown at the call site, you better get it right. This frees you from having to maintain header files, but for various reasons, it is no longer recommended.
// In func.c
// Default to int return
func(x, y)
int x;
int y;
{
return x + y;
}
// In main.c
main(argc, argv)
int argc;
char **argv;
{
int result = func(2, 3);
}
This causes problems if you get the function parameter types wrong.
int result = func(2.0, 3,0); // Wrong, but no compiler error or warning
It was normal to call functions without including the relevant header file. But you need to declare the function return type.
// This is NOT a function prototype, it just declares the return type.
double sin();
double one = sin(3.14); // Correct
double zero = sin(0); // WRONG
double zero = sin(0.0); // Correct
Old style functions are still allowed by the standard, except the default return type is gone. This allows you to compile old programs. For new programs, the -Wmissing-prototypes
option in GCC helps you to avoid using the old style by accident.
int func(); // Old-style, can take any number of arguments.
int func(void); // New-style, takes no arguments, is a function prototype.