首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >函数原型-关闭参数检查

函数原型-关闭参数检查
EN

Stack Overflow用户
提问于 2017-02-04 08:06:08
回答 5查看 144关注 0票数 6

从关于C的K&R书中,我推测如果函数原型声明省略了参数(就像在int foo();中一样),类型和参数检查将被关闭,并且不会假设参数与C的旧版本兼容,因此它不会破坏遗留代码。

但是下面的代码抛出了一个原型不匹配的编译错误:

代码语言:javascript
复制
#include <stdio.h>
void test();
int main(void) {
    test(34.5f);
}

void test(float a) {
    printf("%f\n", a);
}

错误:

代码语言:javascript
复制
C:\***.c:7:6: error: conflicting types for 'test'
 void test(float a) {
      ^

有什么解释吗?

EN

回答 5

Stack Overflow用户

发布于 2017-02-04 08:21:25

当一个函数被多次声明时,所有声明必须具有兼容的类型(C11 6.2.7/2)。在您的代码中,f被声明了两次--该定义也被视为一个声明。

兼容函数类型的定义见C11 6.7.6.3/15:

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

因此,void test()void test(float)是不兼容的。换句话说,在看到void test();之后,任何原型都必须只使用默认参数提升未更改的类型。在这些促销活动下,float将更改为double

我相信从第一个C标准开始就是这样。

票数 5
EN

Stack Overflow用户

发布于 2017-02-04 08:24:55

使用double类型的参数定义函数。

代码语言:javascript
复制
void test(double a) {
    //...
}

问题出在这个调用中

代码语言:javascript
复制
test(34.5f);

使用默认的参数提升将参数转换为双精度类型。

票数 1
EN

Stack Overflow用户

发布于 2017-02-04 13:13:07

根据错误消息,具有默认提升的参数类型不能与空的参数名列表声明匹配。因此,问题是float将被提升为int,这将导致与函数定义的float参数不匹配。

声明:

代码语言:javascript
复制
void test();

它告诉编译器存在一个函数test,它没有参数,也不返回值。

定义:

代码语言:javascript
复制
void test(float a)

它告诉编译器test()到底是什么,还提供了声明。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42034962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档