隐式函数声明在C89中合法吗?

隐式函数声明在C89中合法吗?,c,language-lawyer,c89,C,Language Lawyer,C89,考虑一下这个C程序: int main() { puts("Hello world!"); return 0; } 这编译和运行良好,据我所知,是合法的C89。然而,我不是100%确定。在C99模式下使用clang编译时,我发现函数“puts”的隐式声明在C99中无效(这使我认为C标准在C99中一定发生了更改,使隐式函数声明非法,这正是我试图确认的) 隐式函数声明在C89中合法吗?(即使这样做是一个坏主意(除非您在一个模糊的C代码挑战中) 隐式函数声明在C89中合法吗 对。发件

考虑一下这个C程序:

int main()
{
    puts("Hello world!");
    return 0;
}
这编译和运行良好,据我所知,是合法的C89。然而,我不是100%确定。在C99模式下使用clang编译时,我发现函数“puts”的
隐式声明在C99中无效(这使我认为C标准在C99中一定发生了更改,使隐式函数声明非法,这正是我试图确认的)

隐式函数声明在C89中合法吗?(即使这样做是一个坏主意(除非您在一个模糊的C代码挑战中)

隐式函数声明在C89中合法吗

对。发件人:

如果中括号参数列表前面的表达式 函数调用仅由标识符组成,如果没有 声明对此标识符可见,标识符为 在包含 函数调用,声明

    extern int  identifier();
出现了


隐式函数声明在C89中是合法的,但在C99中被删除。这可以在C11(ISO/IEC 9899:201x)标准中确认

在C11转发部分,它列出了第三版(即C11)和第二版(即C99)中的所有主要更改,其中之一是:

第二版的主要变化包括:

-删除隐式函数声明

    extern int  identifier();
同样在§6.5.2.2函数调用中

C99的一个新特性:C99中删除了隐式声明函数的规则。这样做的效果是确保生成一个诊断,该诊断将捕获额外类别的编程错误。发出诊断后,实现可以选择采用隐式声明并继续转换,以支持利用此功能的现有程序


可能会对您有所帮助。在这种特殊情况下,它具有定义良好的行为,只是因为
put
碰巧返回
int
结果。对于非
int
函数,行为将是未定义的。当然,最好还是添加
#include
。此外,使用
printf()
会调用未定义的行为,因为变量参数列表函数,如
printf()
,即使在C89中也必须正确声明。在范围内没有原型的情况下调用它们不是一个好主意。