关于C函数原型和编制问题 [英] Questions about C Function Prototypes and Compilation

查看:104
本文介绍了关于C函数原型和编制问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过以​​下code:

  INT的main(){
    的printf(%F \\ N,乘(2));
    返回0;
}浮动乘法(浮点N){
    返回N * 2;
}

当我尝试编译我得到一个警告:'%F'预计'双',但参数的类型'诠释'和两个错误:冲突的类型'乘',previous隐声明'乘'在这里。

问题1 :我猜测这是因为,由于编译器没有的功能乘法,当他遇到它的第一次,他将创造一个原型的知识,并发明原型总是假设'诠释'既是返回,并作为参数。这样的本发明的原型是整数乘法(int)的,并因此错误。这是正确的?

现在,在previous code甚至不会编译。但是,如果我突破code在两个文件中是这样的:

 #file1.c中
 诠释主(){
    的printf(%F \\ N,乘(2));
    返回0;
 }#file2.c中
浮动乘法(浮点N){
    返回N * 2;
}

和执行海湾合作委员会在file1.c file2.c中-o文件,它还是会给予一次警告(即printf的期待双,但越来越INT),但误差不会出现了,它会编译。

问题2 :为什么当我突破code到2个文件它编译

问3 :当我运行上面的程序(版本分裂成2个文件)的结果是0.0000印在屏幕上。怎么来的?我猜编译器重新发明了一种原型不匹配的功能,但为什么是0打印?如果我改变的printf(%F)对printf(%D),它打印1.再次,这是怎么回事幕后的任何解释?

非常感谢在前进。


解决方案

  

于是所发明的原型将是INT乘法(INT),并因此错误。这是正确的?


当然可以。这对于pre-ANSI C的向后兼容性,缺乏函数原型做,什么都没有宣布一个类型是隐含 INT 。编译器编译你的,创建 INT乘以(INT)的一个隐含的定义,但是,当它找到真正的定义,它发现了谎言,并告诉你这件事。


  

为什么当我突破code到2档它编译?


编译器从未发现的谎言原型,因为它编译一个文件时:它假定需要一个 INT ,并返回一个 INT 的,并没有发现任何矛盾 multiply.c 。运行这个程序产生不确定的行为,虽然。


  

在我上面跑(版本分裂成2个文件),该程序的结果是0.0000印在屏幕上。


这是上述未定义行为的结果。该程序可以编译和链接,但因为编译器认为需要一个 INT ,它永远不会转换 2 2.0F 永远不会发现。同样的,不正确的值加倍的 INT reinter preTED 的一个浮动里面的功能将被视为一个 INT 试。

With the following code:

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

float multiply(float n){
    return n * 2;
}

When I try to compile I get one warning: "'%f' expects 'double', but argument has type 'int'" and two errors: "conflicting types for 'multiply'", "previous implicit declaration of 'multiply' was here."

Question 1: I am guessing that it's because, given the compiler has no knowledge of function 'multiply' when he comes across it the first time, he will invent a prototype, and invented prototypes always assume 'int' is both returned and taken as parameter. So the invented prototype would be "int multiply(int)", and hence the errors. Is this correct?

Now, the previous code won't even compile. However, if I break the code in two files like this:

#file1.c
 int main(){
    printf("%f\n",multiply(2));
    return 0;
 }

#file2.c
float multiply(float n){
    return n * 2;
}

and execute "gcc file1.c file2.c -o file" it will still give one warning (that printf is expecting double but is getting int) but the errors won't show up anymore and it will compile.

Question 2: How come when I break the code into 2 files it compiles?

Question 3: Once I run the program above (the version split into 2 files) the result is that 0.0000 is printed on the screen. How come? I am guessing the compiler again invented a prototype that doesn't match the function, but why is 0 printed? And if I change the printf("%f") to printf("%d") it prints a 1. Again, any explanation of what's going on behind the scenes?

Thanks a lot in advance.

解决方案

So the invented prototype would be "int multiply(int)", and hence the errors. Is this correct?

Absolutely. This is done for backward compatibility with pre-ANSI C that lacked function prototypes, and everything declared without a type was implicitly int. The compiler compiles your main, creates an implicit definition of int multiply(int), but when it finds the real definition, it discovers the lie, and tells you about it.

How come when I break the code into 2 files it compiles?

The compiler never discovers the lie about the prototype, because it compiles one file at a time: it assumes that multiply takes an int, and returns an int in your main, and does not find any contradictions in multiply.c. Running this program produces undefined behavior, though.

Once I run the program above (the version split into 2 files) the result is that 0.0000 is printed on the screen.

That's the result of undefined behavior described above. The program will compile and link, but because the compiler thinks that multiply takes an int, it would never convert 2 to 2.0F, and multiply will never find out. Similarly, the incorrect value computed by doubling an int reinterpreted as a float inside your multiply function will be treated as an int again.

这篇关于关于C函数原型和编制问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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