C编译器与旧风格的函数原型无行为 [英] The behavior of a C compiler with old-styled functions without prototypes

查看:119
本文介绍了C编译器与旧风格的函数原型无行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的程序包括两个文件:

When my program consists of two files:

的main.c

#include <stdio.h>

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

func.c

func.c

double f(int a) {
 return 1;
}

编译器不显示任何错误。

compiler do not show any 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;
}

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

Visual C++ 2008 compiler show the following error:

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

任何人都可以解释这种奇怪的行为?

Can anybody explain this strange behavior?

推荐答案

这两个程序是错误的。

如果没有范围的原型,编译器假定函数返回 INT ,并采取参数数目不详。

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 <stdio.h>

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

当我编译它,GCC警告我(的Visual C ++也应该在一致性模式)。但是,让我们忽略了警告。

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

它没有打印1,但印刷0。这是因为编译器假定 F()返回 INT ,并分配 D = F(); 转换的 INT 发送。编译器还编制了code,因为它不能告诉大家, F()没有定义它的方式(隐含的)声明。但是在编译上面的程序不被标准所要求的,所以编译器可以拒绝它(试着用 GCC -Werror 例如!)

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.

大多数编译器不会拒绝的第一个程序,因为他们不知道你有没有在其他翻译单元或不是函数 F()的正确定义。他们拒绝第二个方案,因为他们的知道的,你不知道。

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.

这篇关于C编译器与旧风格的函数原型无行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆