Definition of `int foo() {}` vs `int foo(void) {}` following declaration of `int foo(void);` [duplicate]

ε祈祈猫儿з 提交于 2020-04-13 06:39:11

问题


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.

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; }

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?


回答1:


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

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.)

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.


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.



来源:https://stackoverflow.com/questions/60517172/definition-of-int-foo-vs-int-foovoid-following-declaration-of-int

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!