为了账号安全,请及时绑定邮箱和手机立即绑定

C函数调用:了解“隐式int”规则

/ 猿问

C函数调用:了解“隐式int”规则

C
萧十郎 2019-12-06 10:52:21

如果“函数”是分别编译的,则不会检测到不匹配,“函数”将返回一个将main视为int的双精度...根据我们所说的关于声明如何必须与定义匹配的说法,这可能似乎令人惊讶。可能会发生不匹配的原因是,如果没有函数原型,则该函数会通过其在表达式中的首次出现来隐式声明,例如


    sum += "the function"(line);

如果在表达式中出现一个之前未声明的名称,并在其后加上左括号,则上下文将其声明为函数名称,假定该函数返回一个int值,并且不假设其参数成立。


对于这个模棱两可的问题,我事先表示歉意,但这意味着什么呢?


顺便说一下,这是Brian W. Kernighan和Dennis M. Ritchie的C编程语言第二版的第73页第4.3章。


查看完整描述

3 回答

?
慕仰1329654

K&R2涵盖了1989/1990版本的语言。当前的ISO C标准于1999 2011 年发布,它删除了“隐式int”规则,并且要求您对任何调用的函数进行可见声明。编译器不一定默认会强制执行此操作,但是您应该能够请求更严格的警告-而且您绝对应该这样做。在编写良好的新代码中,该规则是不相关的(但必须理解它)。


例如:标准sqrt()函数在中声明<math.h>:


double sqrt(double);

如果您在没有要求的情况下拨打电话#include <math.h>:


double x = 64.0;

double y = sqrt(x);

一个C90编译器将假设该sqrt收益int-它会生成代码的结果,从转换int到double。结果将是垃圾,或者可能是崩溃。


(您可以手动声明sqrt自己,但这是错误的解决方案。)


所以不要那样做。始终包括调用的任何函数所需的标头。如果返回未声明的函数int(并且您的编译器未强制执行严格的C99或C11语义,并且满足其他一些条件),则可能无需调用它,但是没有充分的理由这样做。


理解“隐式int”规则对于理解旧的或编写得不好的代码的行为仍然很有用,但是在任何新代码中都不要依赖它。


查看完整回答
反对 回复 2019-12-06
?
POPMUISE

函数原型后来被引入该语言。

在原型设计之前,编译器将假定传递给每个未知函数的每个参数都应作为整数传递,并假定返回值也是整数。

在少数正确的情况下,这种方法很好用,但是这意味着人们必须以尴尬的顺序编写程序,以使函数永远不会依赖符合此期望的未知函数。

当将原型引入C89(也称为ANSI C或ISO C)时,这些原型使编译器确切地知道需要哪种类型的参数以及将返回哪种类型的结果。

强烈建议您对所有新代码使用函数原型;在完全旧的代码库上工作时,原型可能有害。(或者,如果代码必须在ANSI C之前的编译器上可编译,那么您可能希望放弃原型,以便可以在古老的软件上进行构建。这gcc是我很长时间以来唯一看到的地方。 )


查看完整回答
反对 回复 2019-12-06
?
当年话下

只是说明,如果编译器遇到了调用未知函数的代码,那么它将隐式地将其视为已看到已声明形式的原型 int unknown();


查看完整回答
反对 回复 2019-12-06

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信