Why do you think there needs to be a declaration beyond the definition? The definition is enough information for the compiler, and having both is a DRY violation.
Header files are a historical legacy from when C was developed. Because machines were small compilers/languages were designed to do single pass compilation on modules which were then linked.
Friends of mine who are actual CS majors say with C it's not fixable without changes to the language. With Java or C# the compiler can do a pass and extract the object definitions. But because of ambiguous syntax and majorly because of the preprocessor it's not possible with C as it stands.
You need the declarations because the compiler requires it, it's not something that I just thought up. If you don't, then you get two different declarations for bar in the following. The one you intended (char bar(int)) and the one you didn't (int bar()):
int foo(int n) {
char c = bar(n);
...
}
char bar(int n) { ... }
The definition is not enough information for the compiler in a case like this, which is also essentially the case for any externally defined function. The compiler doesn't know anything about those unless its declaration is provided, which is what's in the header files.
Did I say there were two definitions? I said there are two declarations. Try using a function with a return type other than int before it has been defined or declared in C and see what happens when you compile it.
The function is declared/defined/described/written once, and used once. There is no ambiguity.
I don't understand your point about using a function that hasn't been declared. Of course it won't work!
I understand your point about using header files as interfaces to third-party code, but there are ways of doing that that don't involve duplicating all functions, structs etc.
The function is used once, and because it occurs before the actual definition (and there was no forward declaration) an implicit declaration occurs (the erroneous int bar()). When the function definition is later reached by the compiler, its signature doesn't match the implicit declaration's signature, causing the problem. If the function signature matches the implicit declaration, then there is no problem:
int main(int argc, char* argv[]) {
printf("%d\n", foo(10));
return 0;
}
int foo(int n) {
return n - 1;
}
Will work just fine, giving you only a warning but will print out "9" as expected.
> an implicit declaration occurs (the erroneous int bar()
I still don't understand; why does the implicit declaration assume int bar() is the signature when bar is being passed an int and returning a value to a char?
You don't need type inference to handle this correctly, you just need to wait until you've parsed the rest of the file and seen the signatures of all functions.
Why do you think there needs to be a declaration beyond the definition? The definition is enough information for the compiler, and having both is a DRY violation.