【问题标题】:GCC Warning: implicit declaration of function 'puts' is invalid in C99GCC 警告:函数“puts”的隐式声明在 C99 中无效
【发布时间】:2013-05-28 10:30:26
【问题描述】:

我开始使用 Zed Shaw 的 Learn C The Hard Way。我已经下载了 XCode 和命令行工具。但是当我编译第一个程序时:

int main(int argc, char *argv[]) {
     puts("Hello world."); 
     return 0;
 }

我收到此警告:

ex1.c:2:1:警告:函数“puts”的隐式声明无效 在 C99 中 [-Wimplicit-function-declaration]

程序确实编译并正确执行。

我使用的是 OSX 10.8.3。输入'gcc -v' 给出:

使用内置规范。目标:i686-apple-darwin11 配置: /private/var/tmp/llvmgcc42/llvmgcc42-2336.11~182/src/configure --disable-checking --enable-werror --prefix=/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2 --mandir=/share/man --enable-languages=c,objc, c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/ lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2336.11~182/dst-llvmCore/Developer/usr/local --program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11 --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/4.2.1线程模型:posix gcc 版本 4.2.1(基于 Apple Inc. build 5658)(LLVM build 2336.11.00)

请帮忙。

【问题讨论】:

  • 在未使用参数时使用int main(int argc, char *argv[]) 有点愚蠢;它应该是int main(void) 甚至是int main()。但是,这可能是另一天的辩论。我注意到 GCC 5.x 使用 C11 (-std=gnu11) 作为默认编译模式。 clang(伪装成gcc)使用C99。 C99 和 C11 都要求在使用之前声明所有函数(main() 除外)。

标签: macos gcc


【解决方案1】:

这本“书”应该重命名为Learn To Hate C By Followinglessed Examples That are Blatantly Wright.

现代 C 中的正确代码应该是简单明了的

#include <stdio.h>        // include the correct header

int main(void) {          // no need to repeat the argument mantra as they're not used
    puts("Hello world."); 
}                         // omit the return in main as it defaults to 0 anyway

原来的例子

int main(int argc, char *argv[]) {
    puts("Hello world."); 
    return 0;
}

在 1989 年,在 1999 (即写此答案之前 18 年,几乎与“书" 被写入)C 标准被修订。在 C99 修订版中,这种implicit function declaration 被定为非法 - 和naturally it remains illegal in the current revision of the standard (C11)。因此使用puts 没有#includeing 相关标头,即在#include &lt;stdio.h&gt; 前面(或用int puts(const char*); 声明puts 函数)是一个约束错误 .

约束错误是必须导致编译器输出诊断消息的错误。此外,此类程序被视为无效程序。然而,C 标准的特殊之处在于它允许 C 编译器也成功编译无效程序,尽管编译器也可能会拒绝它。因此,在一本应该向初学者教授 C 语言的书中,这样的例子并不是一个好的起点。

【讨论】:

  • 那个链接是官方标准网站/存储库的东西吗?
  • @Ungeheuer 不,不幸的是official standard 需要花钱。这是 C11 最终 draft 的 HTML 版本,其工作名称为 n1570
  • 谢谢哥们。最后一个问题。链接的网站是否有以前的标准?我看不出有办法离开那里。
  • 标准在哪里规定任何违反约束的程序都是“无效程序”?一个实现可以随意接受或不接受这样的程序,只要它发出诊断,并且如果存在任何接受某些特定文本块的符合 C 实现,则该文本块是符合 C 程序。
【解决方案2】:

你需要包含stdio.h,即

#include <stdio.h> 

在开始时导入函数定义。

【讨论】:

  • 同样在第 2 课中,Zed 指出您可以通过使用 include 语句来消除警告。所以我把正确答案归功于你。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-07
  • 2023-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多