为啥空声明适用于带有 int 参数的定义,但不适用于 float 参数?
Posted
技术标签:
【中文标题】为啥空声明适用于带有 int 参数的定义,但不适用于 float 参数?【英文标题】:Why does an empty declaration work for definitions with int arguments but not for float arguments?为什么空声明适用于带有 int 参数的定义,但不适用于 float 参数? 【发布时间】:2011-07-25 19:01:01 【问题描述】:我认为区别在于declaration
没有参数类型...
为什么会这样:
int fuc();
int fuc(int i)
printf("%d", i);
return 0;
但是编译失败:
int fuc();
int fuc(float f)
printf("%f", f);
return 0;
带有消息:
错误:“fuc”的类型冲突。注意:具有默认提升的参数类型不能匹配空参数名称列表声明
【问题讨论】:
第二个例子编译失败时编译器会告诉什么? @xappymah,来自 gccerror: conflicting types for ‘fuc’. note: an argument type that has a default promotion can’t match an empty parameter name list declaration
相关:***.com/questions/12643202/…
【参考方案1】:
prototype = 前向声明,因此您可以在告诉编译器它做什么之前使用它。但是,它仍然有参数。
在很多方面都很有用!
【讨论】:
如果prototype = forward declaration
,那么forward declaration
和declaration
有什么区别??
前向声明在实际声明之前。前向声明 = void hi();声明 = void hi() printf("hi"); 【参考方案2】:
声明int fuc(float);
告诉编译器存在一个函数fuc
,它接受float
并返回int
。
定义int fuc(float f) /*...*/
告诉编译器fuc
实际上是什么,并且还提供了声明。
声明和定义之间的区别在于说存在 6 号蓝色帽子和将 6 号蓝色帽子交给某人之间的区别:声明说有这样的事情,定义说这件事就在这里是有问题的。
【讨论】:
【参考方案3】:声明:
int f();
...告诉编译器某个标识符(在这种情况下为f
)命名了一个函数,并告诉它函数的返回类型——但是没有指定数字或该函数打算接收的参数类型。
原型:
int f(int, char);
...在其他方面类似,但也指定函数打算接收的参数的数量/类型。如果它不带参数,则使用int f(void)
之类的东西来指定(因为将括号留空是一个声明)。一种新式的函数定义:
int f(int a, char b)
// do stuff here...
...也可以作为原型。
如果没有原型,编译器会在调用函数之前对参数应用默认提升。这意味着任何char
或short
被提升为int
,任何float
被提升为double
。因此,如果您声明(而不是原型)一个函数,您确实不想要指定任何 char
、short
或 float
参数——调用这样的东西会/将给出 undefined行为。使用默认标志,编译器很可能会拒绝代码,因为基本上没有办法正确使用它。您也许可以找到一些编译器标志,让它接受代码,但这毫无意义,因为无论如何您都不能使用它......
【讨论】:
有趣,我以前不知道这些促销活动。显然 C 有一个叫做 默认参数提升 的东西(C99 6.5.2.2.6)。 C 语言中有太多隐藏的怪异之处!我想知道为什么他们将这个令人难以置信的丑陋“补丁”添加到标准中,而不是强制执行原型。无论如何,C 工作组的“未来语言扩展”建议,如果他们制作了新版本的标准,所有这些废话都将从标准中删除。 他们几乎没有必要保留默认促销:原型是原始 C 标准化期间的一项新发明。要求原型会破坏 100% 的现有代码和编译器... 你的说法似乎表明原型不是声明(没有参数类型 -> 声明,有参数类型 -> 原型)。 @undur_gongor:当然,原型也声明了函数,但是是的,听起来你已经理解了我试图做出的区分。以上是关于为啥空声明适用于带有 int 参数的定义,但不适用于 float 参数?的主要内容,如果未能解决你的问题,请参考以下文章
AutoLayout 适用于 UIView 但不适用于 UILabel。为啥?
带有嵌套地图的 Promise.all .. 第一张地图仅适用于其他人在猫鼬中返回空对象
vue中将汉字按照首字母排序,也适用于其他地方,但不适用多音字
错误:在 lambda 参数声明中使用 'auto' 仅适用于 -std=c++1y 或 -std=gnu++1y [-Werror]