0

我有这两个文件:

// first.c
int main(void) {
  putint(3);
}

// second.c
#include <stdio.h>
void putint(int n) {
  printf("%d",n);
  getchar();
}

当我在 Win XP 下运行 gcc 4.6.1 时:

gcc first.c second.c -o program.exe

它没有问题,并将 3 写入标准输出。它不需要putintfirst.c中声明。这怎么可能?这是标准行为吗?

我已经在 MSVC 2008 Express 上对此进行了测试,它仅在声明的情况下运行,如预期的那样。

// first.c
void putint(int);
int main(void) {
  putint(3);
}

已解决,感谢提示,这些选项有助于显示警告:

  • -Wimplicit
  • -std=c99 (MinGW 4.6 默认仍使用gnu90 )
4

3 回答 3

2

这是几十年前不应该使用的 C 的遗留“功能”。您应该使用带有设置的编译器,如果您执行此类操作,该编译器会向您发出警告。Gcc 有几个开关,你应该在使用它时指定它们,其中一个会给你一个警告。

编辑:我自己没有使用过 gcc,但您应该检查的开关是 -pedantic、-Wall、-Wextra 和 -std。

接受这一点的编译器假设,根据旧语言定义,由于您认为不适合告诉它,因此函数 a) 返回一个 int 值,b) 因为您将它传递给 int(或者如果您传递它可以提升为 int 的东西)该函数期望该参数是一个 int。

正如@veer 正确指出的那样,这通常应该适用于您的特定情况。然而,在其他情况下,没有原型的函数的隐含假设与函数的实际签名之间的差异会使事情变得繁荣。

于 2012-08-30T00:28:34.030 回答
2

这不仅适用于 MinGW,而且适用于所有标准版本的 gcc。如前所述,这在 C89 中是合法的;gcc 默认为 'gnu89'(不是 99),它也接受代码而不发出警告。如果您切换到 c99 或 gnu99(或更高版本,例如 c11),默认情况下会收到警告,但仍会编译。

于 2012-08-30T01:05:36.563 回答
0

正如其他人所指出的,这是符合 C 的编译器的标准行为。将文件命名为 .c 部分会将其置于 C 模式。它会有一些有趣的东西,比如“内置函数”(printf() 等)和各种遗留的 C 东西。

不过,我想补充一下我最近经历的其他人所说的话。MS 明确放弃了对 C 超过 C90 的支持,至少可以说他们的 C90 支持很差。我不完全确定标准 ANSI C90 代码库会在较新的 VS 下编译,因为它基本上是禁用了很多东西的 C++ 编译器(而 GCC 实际上有一个 C 编译器)。他们这样做是为了推广 C++。如果你想使用真正的 C,你不能在任何版本的 MS Visual Studio 中真正做到这一点,除非你想在函数的开头声明所有变量等。

于 2012-08-30T02:38:17.663 回答