C compiler behavior with old functions without prototypes

When my program consists of two files:

main.c

#include <stdio.h> int main(void) { printf("%lf\n",f()); return 0; } 

func.c

 double f(int a) { return 1; } 

does not detect errors.

When my program consists of only one file:

main.c

 #include <stdio.h> int main(void) { printf("%lf\n",f()); return 0; } double f(int a) { return 1; } 

The Visual C ++ 2008 compiler shows the following error:

 Error 2 error C2371: 'f' : redefinition; different basic types d:\temp\projects\function1\function1\1.c 8 function1 

Can anyone explain this weird behavior?

+5
c function implicit declaration function-prototypes
source share
3 answers

Both programs are erroneous.

Without a prototype in scope, the compiler assumes that the function returns an int and accepts an indefinite number of parameters.

Modify your files a bit:

 $ cat func.c double f(int a) { return 1.0; } $ cat main.c #include <stdio.h> int main(void) { double d = f(); printf("%lf\n", d); return 0; } 

When I compile it, gcc warns me (Visual C ++ should also be in negotiation mode). But let him ignore the warning.

 $ gcc -std=c99 -pedantic -W -Wall func.c main.c -o test func.c:1: warning: unused parameter 'a' main.c: In function 'main': main.c:4: warning: implicit declaration of function 'f' $ ./test 0.000000 

He did not print 1, but print 0. This is because the compiler suggested that f() returns int , and the assignment d = f(); converts to int "on double . The compiler still compiled the code because it could not say that f() not defined as it was (implicitly) declared. But compilation of the above program is not required by the standard, so the compiler could reject it (e.g. using gcc -Werror !)

If we have everything in one file:

 $ cat func.c >>main.c $ gcc -std=c99 -pedantic -W -Wall func.c main.c -o test main.c:4: warning: implicit declaration of function 'f' main.c: At top level: main.c:9: error: conflicting types for 'f' main.c:4: error: previous implicit declaration of 'f' was here main.c:9: warning: unused parameter 'a' 

Now the compiler sees the conflict and gives an error message. But the compiler is not required to reject the above program, it may or may not be.

Most compilers do not reject the first program because they do not know if you have the correct definition of the f() function in another translation unit or not. They reject the second program because they know that you are not doing this.

+5
source share

C will assume that the function has a prototype int func (); unless you say otherwise. (Note that in C, int func () and int func (void) are two different things)

In your second case, you call f() , for which the compiler has not seen any prototype, so it assumes that it is int f(); . Later, he sees your definition for f() , which has a different prototype, and throws an error.

This does not happen in case 1., since they are in different compilation units.

+6
source share

In your first example, func.c never used, so I'm not sure exactly what the compiler does for f() , because it has no definition.

In the second example, I don’t know why you cannot have two functions with different signatures, but you do not name the function that you defined. You call f() with no arguments, but the f you define takes an int, which makes it another function.

0
source share

All Articles