c - 隐式函数声明的行为

标签 c function-declaration implicits function-definition

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

测试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: error: conflicting types for 'xof' int xof(char c,float 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' 具有“未定义的垃圾”

-1 12260176

有人可以解释一下吗? 提前致谢。

最佳答案

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

对于第一个程序,生成的错误消息是:

/tmp/x1.c:10: error: conflicting types for ‘xof’
/tmp/x1.c:10: note: an argument type that has a default promotion can’t match an empty parameter name list declaration
/tmp/x1.c:6: error: previous implicit declaration of ‘xof’ was here

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

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

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

关于c - 隐式函数声明的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44877021/

相关文章:

javascript - 函数返回未声明的变量

c++ - 为什么括号被消除歧义为 std::istream_iterator 的函数声明?

scala - 含糊不清的隐含

scala - 为什么没有找到琐碎的隐式?

java - 给定 'getrand100()' 函数获取特定范围内的随机数

c - 给定一个 32 位无符号随机数,如何在一定范围内操作值 [low, high]?

c - 结构成员的默认对齐方式

javascript - 带三元运算符的函数声明

scala - 使用 -Ywarn-unused 时从 Scala 中的分析中排除类型证据参数

C 为什么DBL_MANT_DIG宏定义为53