为啥空声明适用于带有 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,来自 gcc error: 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 declarationdeclaration有什么区别?? 前向声明在实际声明之前。前向声明 = 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...

...也可以作为原型。

如果没有原型,编译器会在调用函数之前对参数应用默认提升。这意味着任何charshort 被提升为int,任何float 被提升为double。因此,如果您声明(而不是原型)一个函数,您确实想要指定任何 charshortfloat 参数——调用这样的东西会/将给出 undefined行为。使用默认标志,编译器很可能会拒绝代码,因为基本上没有办法正确使用它。您也许可以找到一些编译器标志,让它接受代码,但这毫无意义,因为无论如何您都不能使用它......

【讨论】:

有趣,我以前不知道这些促销活动。显然 C 有一个叫做 默认参数提升 的东西(C99 6.5.2.2.6)。 C 语言中有太多隐藏的怪异之处!我想知道为什么他们将这个令人难以置信的丑陋“补丁”添加到标准中,而不是强制执行原型。无论如何,C 工作组的“未来语言扩展”建议,如果他们制作了新版本的标准,所有这些废话都将从标准中删除。 他们几乎没有必要保留默认促销:原型是原始 C 标准化期间的一项新发明。要求原型会破坏 100% 的现有代码和编译器... 你的说法似乎表明原型不是声明(没有参数类型 -> 声明,有参数类型 -> 原型)。 @undur_gongor:当然,原型也声明了函数,但是是的,听起来你已经理解了我试图做出的区分。

以上是关于为啥空声明适用于带有 int 参数的定义,但不适用于 float 参数?的主要内容,如果未能解决你的问题,请参考以下文章

AutoLayout 适用于 UIView 但不适用于 UILabel。为啥?

带有嵌套地图的 Promise.all .. 第一张地图仅适用于其他人在猫鼬中返回空对象

Swift @escaping 仅适用于非空函数参数?

vue中将汉字按照首字母排序,也适用于其他地方,但不适用多音字

空F#区分联合案例的C#类型

错误:在 lambda 参数声明中使用 'auto' 仅适用于 -std=c++1y 或 -std=gnu++1y [-Werror]