为什么带有空参数列表的函数原型与具有char参数的函数原型冲突? [英] Why does a function prototype with an empty argument list conflicts with one that has a char argument?

查看:86
本文介绍了为什么带有空参数列表的函数原型与具有char参数的函数原型冲突?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用以下代码,用-std = c11调用的clang和gcc都抱怨foo的类型冲突。

With the code below, both clang and gcc called with -std=c11 complain about conflicting types for foo.

int foo();

int main(void) {
  return foo(0);
}

int foo(char a) {
   return a;
}

根据 https://stackoverflow.com/a/13950800/1078224 ,在(较旧的)C标准中,如果未给出任何变量类型,则假定类型为int。但是,C11标准草案( http:// www .open-std.org / jtc1 / sc22 / wg14 / www / docs / n1570.pdf ),第6.7.6.3节,$ 14表示

According to the answer in https://stackoverflow.com/a/13950800/1078224, in (older?) C standards the type int has been assumed when no variable type was given. However, the C11 standard draft (http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf), section 6.7.6.3, $14 says that


函数声明器中的空白列表(不属于该函数的
定义)指定未提供有关
参数的数量或类型的信息。

The empty list in a function declarator that is not part of a definition of that function specifies that no information about the number or types of the parameters is supplied.

据此我得出结论,上面的代码实际上应该是有效的。还是我遗漏了该标准的其他相关部分?

From this I conclude that the code above should be actually valid. Or am I missing some other relevant section of the standard?

推荐答案

C 2011(N1570)6.7.6.3 15:

C 2011 (N1570) 6.7.6.3 15:


要使两个函数类型兼容,两者都应指定兼容的返回类型。此外,如果同时存在参数类型列表,则应在参数数量和省略号终止符的使用上达成共识;相应的参数应具有兼容的类型。如果一种类型具有参数类型列表,而另一种类型由不包含在函数定义中且包含空标识符列表的函数声明符指定,则该参数列表不得包含省略号和每个参数都应与应用默认参数Promotions产生的类型兼容。。…[添加了强调。]

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.… [Emphasis added.]

char 被提升为 int ,因此 char a 与空列表不兼容。 int a 应该是; int foo(); int foo(int a); 是允许的。

char is promoted to int, so char a is not compatible with an empty list. int a would be; int foo(); int foo(int a); is allowed.

本质上,这样做的原因是,如果声明一个函数 int foo()然后调用它,用 int foo(3)说,编译器必须知道要传递什么。源自历史的规则将执行默认参数提升。因此, int foo(3)的调用就像是 int foo(int)一样。

Essentially, the reason for this is that, if you declare a function int foo() and then call it, say with int foo(3), the compiler has to know what to pass it. The rules, derived from history, are to perform the default argument promotions. So int foo(3) gets called as if it were int foo(int).

然后,如果以后使用 int foo(char)定义函数,则该定义将与调用不匹配。在许多C实现中,可以将 char int 放在同一位置以调用函数,但是C实现可能会有所不同。 float double 会产生更大的冲突。

Then, if you later define the function with int foo(char), the definition will not match the call. In many C implementations a char and an int may be put in the same place for calling a function, but a C implementation could do something different. A float and a double would be a greater conflict.

这篇关于为什么带有空参数列表的函数原型与具有char参数的函数原型冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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