【问题标题】: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

标签: c function-declaration function-prototypes


【解决方案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:当然,原型也声明了函数,但是是的,听起来你已经理解了我试图做出的区分。
    猜你喜欢
    • 2015-09-06
    • 2012-06-29
    • 1970-01-01
    • 2014-01-11
    • 1970-01-01
    • 1970-01-01
    • 2022-12-08
    • 1970-01-01
    • 2022-11-05
    相关资源
    最近更新 更多