The behavior of a C compiler with old-styled functions without prototypes

后端 未结 3 1911
自闭症患者
自闭症患者 2020-12-19 12:24

When my program consists of two files:

main.c

#include 

int main(void) { 
     printf(\"%lf\\n\",f());   
     return 0;
 }
         


        
3条回答
  •  天命终不由人
    2020-12-19 12:54

    Both the programs are wrong.

    Without a prototype in scope, a compiler assumes that a function returns int and takes an unspecified number of parameters.

    Let's change your files a bit:

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

    When I compile it, gcc warns me (Visual C++ should too, in conformant mode). But let's 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
    

    It did not print 1, but printed 0. This is because the compiler assumed that f() returned an int, and the assignment d = f(); converted that "int" to a double. The compiler still compiled the code because it couldn't tell that f() wasn't defined the way it was (implicitly) declared. But compiling the above program isn't required by the standard, so the compiler could have rejected it (try with gcc -Werror for example!)

    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 you an error message. But, a compiler is not required to reject the above program, it may or may not.

    Most compilers don't reject the first program because they don't know if you have a correct definition of the function f() in another translation unit or not. They reject the second program because they know that you don't.

提交回复
热议问题