5

当我的程序包含两个文件时:

主程序

#include <stdio.h>

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

函数c

double f(int a) {
 return 1;
}

编译器不显示任何错误。

当我的程序仅包含一个文件时:

主程序

#include <stdio.h>

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

double f(int a) {
 return 1;
}

Visual C++ 2008 编译器显示以下错误:

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

谁能解释这种奇怪的行为?

4

3 回答 3

6

C 将假定函数具有原型 int func(); 除非您另有说明。(请注意,在 C 中 int func(); 和 int func(void); 是不同的东西)

在第二种情况下,您调用f()了编译器没有看到任何原型的调用,因此它假定它是int f();. 稍后它会看到您的定义f()具有不同的原型 - 并发出错误。

这在 1. 的情况下不会发生,因为它们位于不同的编译单元中。

于 2010-02-18T08:32:28.893 回答
5

这两个程序都是错误的。

如果没有范围内的原型,编译器会假定函数返回int并采用未指定数量的参数。

让我们稍微改变一下你的文件:

$ 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;
}

当我编译它时,gcc 会警告我(Visual C++ 也应该在一致模式下)。但是,让我们忽略警告。

$ 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

它没有打印 1,而是打印了 0。这是因为编译器假定f()返回 an int,并且赋值d = f();将 " int" 转换为 a double。编译器仍然编译了代码,因为它无法判断它f()没有按照(隐式)声明的方式定义。但是标准不需要编译上述程序,因此编译器可能会拒绝它(gcc -Werror例如尝试!)

如果我们将所有内容都放在一个文件中:

$ 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'

现在编译器看到了冲突,并给你一个错误信息。但是,编译器不需要拒绝上述程序,它可能会也可能不会。

大多数编译器不会拒绝第一个程序,因为他们不知道您是否f()在另一个翻译单元中对该函数进行了正确定义。他们拒绝第二个程序,因为他们知道你不这样做。

于 2010-02-18T09:04:20.180 回答
0

您的第一个示例从未使用过func.c,因此我不确定编译器到底在做什么,f()因为它没有定义。

在第二个例子中,我不知道为什么你不能有两个具有不同签名的函数,但你没有调用你定义的函数。您f()不带参数调用,但是f您定义的 int 使其成为不同的函数。

于 2010-02-18T08:34:50.557 回答