C函数调用:理解"隐式int"规则

Mat*_*gan 4 c function

如果"a function"是单独编译的,那么就不会检测到不匹配,"函数"会返回一个main,它将main视为一个int ...根据我们所说的声明如何必须匹配定义,这可能会似乎令人惊讶.可能发生不匹配的原因是,如果没有函数原型,则函数通过其在表达式中的第一次出现来隐式声明,例如

    sum += "the function"(line);
Run Code Online (Sandbox Code Playgroud)

如果先前未声明的名称出现在表达式中并且后跟左括号,则上下文将其声明为函数名称,假定该函数返回int,并且不假设其参数.

我事先为这个含糊不清的问题道歉,但这是什么意思?

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

Kei*_*son 10

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

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

double sqrt(double);
Run Code Online (Sandbox Code Playgroud)

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

double x = 64.0;
double y = sqrt(x);
Run Code Online (Sandbox Code Playgroud)

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

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

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

理解"隐式int"规则对于理解旧代码或编写不良的代码的行为仍然有用,但是你不应该在新代码中依赖它.


sar*_*old 7

函数原型最近被引入语言.

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

这适用于少数几个正确的情况,但意味着人们必须以尴尬的顺序编写程序,以便函数永远不会依赖于与此期望匹配的未知函数.

当原型被引入C89(又名ANSI C或ISO C)时,原型允许编译器确切地知道预期的参数类型以及将返回的结果类型.

强烈建议您对所有新代码使用函数原型; 在处理一个完全古老的代码库时,原型可能是有害的.(或者,如果代码必须在ANSI C之前的编译器上编译,那么您可能希望不使用原型,因此可以在古老的软件上构建.这gcc是我在很长一段时间内见过这一点的唯一地方. )