Here is the content of src1.c:
#include <stdio.h>
extern int w;
//int go(char); // no need to declare here. WHY????
main(){
char a='f';
go(a);
printf("%d\n", w);
}
And here is the content of src2.c:
#include <stdio.h>
int w = 99;
int go(char t){
printf("%c\n%d\n",t,sizeof(t));
}
Why isn’t it mandatory to declare the go function in src1.c file after compiling it in Linux?
cc src1.c src2.c;
Does the compiler put the go function’s definition from src2.c file above the main function’s code so that declaration then would not be required?
In I do it this way:
#include <stdio.h>
int go(char); // need to declare here, because if not, arguments of go will be promoted to intS and they would conflict with char parameters defined in go. Error is droped!
main(){
char a='f';
go(a);
}
int go(char t){
printf("%c\n%d\n",t,sizeof(t));
}
So everyone that says, it is possible to pass whatever number and types of arguments in absence of prototype is wrong. They are promoted to ints in this case, but have to agree with those specified in definition.
I did some tests and found out that even it compiles with no errors it does not work correctly.
src1:
#include <stdio.h>
int go(int t){
printf("%d\n%d\n",t,sizeof(t));
}
sr2.c:
#include <stdio.h>
int go(int); //if I omit this prototype, program outputs 1 which is far from correct answer :)
main(){
double b=33453.834;
go(b);
}
So finally the answer could only be undefined behavior.
Thanks Maxim Skurydin
It’s indeed not mandatory to have a prototype for a function before using it, but this is a quirk of the early days of C.
When there is no prototype present, the compiler cannot check the actual types that are being passed to the function or returned by it, which might be very bad in case of mismatch between the usage and declaration.
When compiler sees no prototype for
gowhengo(b);is invoked, it assumes it has the following prototypeint go(<any number of arguments can be there>). The default argument promotions are performed on the arguments prior to function invocation. Of course, if there is no functiongoin another translation module, you will get a linker error.From c99 standard:
update:
No, it doesn’t put anything. A cite of the standard above says that no prototype is necessary. Each file is compiled independently so when src1.c is compiled, it doesn’t know anything about src2.c and a
gofunction definition inside.It is possible and I’ve faced a couple of obscure bugs after system-wide change that compiled just fine without any warnings for some reason (actually, it’s undefined behavior).
Again, since each *.c file is compiled independently, there is now way it can check the number of arguments and their types of
gofunction defined in another translation unit. If the function takes more arguments that you have provided, the “unused” arguments will be filled with some random data. You should keep in mind, that if arguments don’t match – it’s undefined behavior, which means that anything can happen.