【问题标题】:behaviour of implicit function declaration隐式函数声明的行为
【发布时间】:2017-12-06 05:13:35
【问题描述】:

我知道使用没有原型的函数是错误的。 但是当我摆弄时,我遇到了这种奇怪冲突的行为。

测试1

    #include <stdio.h>
    #include <limits.h>
    void main(){
        char c='\0';
        float f=0.0;
           xof(c,f);/* at this point implicit function declaration is 
generated as int xof(int ,double ); */ 
    }
    int xof(char c,float f)
    {
        printf("%d %f\n", c,f);
    }

隐式函数声明将是 int xof(int ,double );

错误是

variablename.c:8:5: 错误: 'xof' int xof(char c,浮动 f)

我理解这一点,因为隐式生成的函数声明(将整数值默认为 INT,小数为 DOUBLE)与以下函数定义不匹配

测试2

#include <stdio.h>


 #include <limits.h>
    void main(){
        unsigned int a =UINT_MAX;
        int b=0;
        xof(a); /* implicit function declaration should be int xof(int); */
    }

    int xof(unsigned a,int b)
    {
        printf("%d %d\n", a,b);
    }

隐式函数声明将是 int xof(int); 这应该与函数定义冲突

但这运行良好(没有错误),输出是 'a' 表现为 'int' 值,而 'b' 具有 'undefined Garbage'

-1 12260176

谁能解释一下。 提前致谢。

【问题讨论】:

  • C 需要在使用前正确声明。其他任何东西都是无效的 C!因此,问“为什么这个 C 代码做某事是没有意义的——它不是 C 代码,而且你不使用符合标准的编译器或忽略警告。根据你的介绍,你很清楚。
  • 旧版本的 C 标准允许函数参数推断。第二个例子可以通过这些松散的规则“偷偷摸摸”。这是 C 转为始终要求前向声明的原因之一。
  • 只需更新到不超过 18 年的编译器。那你就不用考虑这些了。
  • 投票重新开放。链接的 dup 询问是否需要函数原型。这个问题询问在什么情况下可以使用隐式声明。

标签: c function-declaration implicits function-definition


【解决方案1】:

当遇到没有定义的函数调用时,生成的隐式定义将始终为int (*)(),即一个函数接受未指定数量的参数并返回int考虑函数调用中的实际参数。这就是你的误解的来源。

在第一个程序的情况下,生成的错误信息是:

/tmp/x1.c:10:错误:“xof”的类型冲突
/tmp/x1.c:10: 注意:具有默认提升的参数类型不能匹配 空参数名称列表声明
/tmp/x1.c:6: 错误:上一个 'xof' 的隐式声明在这里

出现错误是因为实际函数定义包含一个或多个参数,其类型受默认提升规则约束。具体来说,任何等级低于int(在本例中为char)的整数类型在表达式中都被提升为intfloat 参数也是如此,它在表达式中被提升为 double。换句话说,不可能通过隐式声明将正确类型的参数传递给这个函数。

第二个程序不会产生错误,因为两个参数(intunsigned int)都不受默认提升规则的约束。在这种情况下,您调用未定义的行为,因为您没有传递正确类型的正确数量的参数。如果您确实传入了 2 个正确类型的参数,则行为将得到很好的定义。

请注意,隐式函数声明是 C89 的一项功能,在 C99 及更高版本中不受支持,尽管某些编译器仍可能在 C99 或 C11 模式下接受它们作为扩展。

【讨论】:

    猜你喜欢
    • 2021-01-20
    • 1970-01-01
    • 2014-06-28
    • 2022-01-16
    • 2011-10-05
    • 2013-10-28
    • 2019-07-16
    • 2017-07-16
    相关资源
    最近更新 更多