声明`int foo(void);后``int foo(){}`与`int foo(void){}`的定义 [英] Definition of `int foo() {}` vs `int foo(void) {}` following declaration of `int foo(void);`

查看:261
本文介绍了声明`int foo(void);后``int foo(){}`与`int foo(void){}`的定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

注意:这与 func()vs func(void)不同在c99 中,因为此处的问题专门询问在有效的声明之后遵循零参数函数的实现.

Note: this is not the same as func() vs func(void) in c99, because the question here specifically asks about the implementation of a zero-argument function following a valid declaration.

零参数的实现是否应包含void关键字?具体来说,C标准对以下两个功能的实现有什么要说的吗?请注意, foo1foo2都被声明为零参数函数;唯一的区别在于实现,而不是声明:

Should the implementation of a zero-argument include the void keyword? Specifically, does the C standard have anything to say about the implementation of the following two functions? Note that both foo1 and foo2 are declared as zero-argument functions; the only difference is in the implementation, not in the declaration:

#include <stdio.h>

int foo1(void);  // inform compiler that foo1 and foo2 are zero-args fns.
int foo2(void);

int main() {
  printf("%d\n", foo1());
  printf("%d\n", foo2());
  return 0;
}

int foo1(void) { return 22; }
int foo2() { return 22; }

我注意到gcc -Wall -std=c99 -Wpedantic foo.c -o foo可以在没有任何警告或错误的情况下进行编译和执行,但是是否存在违反标准的情况?

I note that gcc -Wall -std=c99 -Wpedantic foo.c -o foo compiles and executes without any warnings or errors, but is there any violation of the standard going on?

推荐答案

您发布的代码正确. int foo2(void);foo2声明为不带任何参数,并形成一个原型.

The code you have posted is correct. int foo2(void); declares foo2 as taking no arguments, and forms a prototype.

函数定义必须与此兼容;并且带有空括号的定义与此原型兼容.这在C11 6.7.6.3/15中有详细说明,这是一个很详尽的说明:

The function definition must be compatible with this; and a definition with empty parentheses is compatible with this prototype. This is specified in C11 6.7.6.3/15, which is a mouthful:

要使两个函数类型兼容,两者都应指定兼容的返回类型.此外,参数类型列表(如果同时存在)应在参数数量和省略号终止符的使用上达成共识;相应的参数应具有兼容的类型.如果一种类型具有参数类型列表,而另一种类型由不属于函数定义一部分且包含空标识符列表的函数声明符指定,则参数列表不应具有省略号终止符,并且每个参数的类型均应为与应用默认参数提升的结果类型兼容. 如果一种类型具有参数类型列表,而另一种类型是由包含(可能为空)标识符列表的函数定义指定的,则两者均应在参数数量和每个原型的类型上达成一致参数应与默认参数的应用所产生的类型兼容 提升为相应标识符的类型. (在确定类型兼容性和复合类型时,将使用函数或数组类型声明的每个参数视为已调整类型,将使用合格类型声明的每个参数视为具有其声明类型的非合格版本.)

For two function types to be compatible, both shall specify compatible return types. Moreover, the parameter type lists, if both are present, shall agree in the number of parameters and in use of the ellipsis terminator; corresponding parameters shall have compatible types. If one type has a parameter type list and the other type is specified by a function declarator that is not part of a function definition and that contains an empty identifier list, the parameter list shall not have an ellipsis terminator and the type of each parameter shall be compatible with the type that results from the application of the default argument promotions. If one type has a parameter type list and the other type is specified by a function definition that contains a (possibly empty) identifier list, both shall agree in the number of parameters, and the type of each prototype parameter shall be compatible with the type that results from the application of the default argument promotions to the type of the corresponding identifier. (In the determination of type compatibility and of a composite type, each parameter declared with function or array type is taken as having the adjusted type and each parameter declared with qualified type is taken as having the unqualified version of its declared type.)

在这一点上有太多文字的原因是C最初仅具有K& R样式函数,然后添加了原型.因此,必须有文字来涵盖K& R样式与原型样式混合的所有可能组合.我的粗体部分开始的部分是指以前用原型声明过函数的情况下,使用K& R样式的函数定义.

The reason there's so much text on this point is that C originally only had K&R style functions, and then prototypes were added . So there has to be text to cover all possible combinations of K&R style mixed with prototype style . The section beginning with my bolded part refers to using a K&R-style function definition when the function has previously been declared with a prototype.

也很重要:在C11(6.11.6)中,空括号的使用已经过时了.

Also relevant: use of empty parentheses is obsolescent in C11 (6.11.6).

某些功能已过时,这意味着可以考虑将它们用于 撤消本国际标准的未来修订版.由于它们的广泛使用而保留了它们,但不建议在新的实现或新程序中使用它们.

Certain features are obsolescent, which means that they may be considered for withdrawal in future revisions of this International Standard. They are retained because of their widespread use, but their use in new implementations or new programs is discouraged.

这篇关于声明`int foo(void);后``int foo(){}`与`int foo(void){}`的定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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