要真正符合标准,C中的所有函数(Main除外)都必须有一个原型,即使它们只是在同一翻译单元中定义之后才使用?

推荐答案

这取决于你所说的"真正符合标准"是什么意思.然而,简短的答案是"在使用之前,确保所有函数都有一个范围内的原型是个好主意".

一个更合格的答案指出,如果函数接受变量参数(特别是printf()系列函数),则原型必须在严格符合标准的范围内.C89(来自ANSI)和C90(来自ISO;除章节编号外与C89相同)也是如此.但是,除了"varargs"函数之外,返回int的函数不必声明,返回int以外的值的函数需要显示返回类型的声明,但不需要参数列表的原型.

但是,请注意,如果函数采用的参数在没有原型的情况下会受到"正常提升"的影响(例如,采用charshort的函数——两者都转换为int;更严重的是,可能采用float而不是double的函数),则需要一个原型.该标准在这方面很宽松,允许旧的C代码在符合标准的编译器下编译;编写旧代码并不是为了确保函数在使用前声明——根据定义,旧代码并没有使用原型,因为直到有了标准,原型才在C中可用.

C99不允许‘IMPLICIT INT’.这意味着既有像‘static a;’(默认情况下是int)这样的奇怪情况,也有隐式函数声明.在ISO/IEC 9899:1999的前言中提到了这些(以及大约50个其他主要变化), 它将该标准与以前的版本进行了比较:

  • 删除隐式int
  • 删除隐式函数声明

在ISO/IEC 9899:1990中,§6.3.2.2 Function calls规定:

如果函数调用中括号参数列表前面的表达式包含

extern int identifier();

出现了38

38也就是说,一个具有块作用域的标识符被声明为具有类型函数的外部链接,而没有

1999年标准中缺少该段.我还没有(至今)跟踪C90中允许static a;而C99中不允许它(需要static int a;)的措辞变化.

请注意,如果函数是静态的,则可以在使用之前对其进行定义,并且不需要在其前面加声明.如果一个非静态函数的定义之前没有声明(-Wmissing-prototypes),那么GCC可以说服witter.

C++相关问答推荐

为指针 struct 创建宏

如何在不修改字符串缓冲区早期使用的情况下覆盖字符串缓冲区

VS代码C/C++扩展intellisense无法检测环境特定函数'

我应该如何解决我自己为iOS编译的xmlsec1库的问题?转换Ctx.first在xmlSecTransformCtxPrepare()之后为空

自定义应用程序上的日志(log)轮换问题

是否所有C编译器在将浮点数转换为整型数时都会隐式删除小数?

Win32API Wizzard97 PropSheet_SetWizButton不工作

使用C时,Windows CMD中的argc参数是否包含重定向命令?

在列表中插入Int指针(C)

具有交换链获取和命令缓冲区提交的同步-危险-读后写错误

使用AVX2的英特尔2022编译器的NaN问题&;/fp:FAST

如何将字符**传递给需要常量字符指针的常量数组的函数

将变量或参数打包到 struct /联合中是否会带来意想不到的性能损失?

类型定义 struct 与简单的类型定义 struct

如何在C中定义指向函数的指针并将该指针赋给函数?

如何在不更改格式说明符的情况下同时支持双精度和长双精度?

OMP并行嵌套循环

从文件到链表读取日期

const struct 成员的 typedef 中的灵活数组大小

memcmp 是否保证按顺序比较字节?