C编译器在未指定类型时不抛出错误

时间:2014-10-23 13:29:31

标签: c gcc implicit-int

为什么以下程序不会抛出错误:

dfljshfksdhfl;
#include <stdio.h>
int main () {
        return 0;
}

gcc会发出警告:

  

test.c:1:1:警告:数据定义没有类型或存储类[默认启用]

3 个答案:

答案 0 :(得分:7)

这是因为即使implicit int is no longer part of the C standard since C99一些编译器仍然支持它,主要是为了防止破坏很多旧代码。所以这一行:

dfljshfksdhfl;

最终相当于:

int dfljshfksdhfl;

clang默认为我们提供了更多信息警告:

warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
dfljshfksdhfl;
^~~~~~~~~~~~~

我们可以使用-pedantic-errors标记将其转换为错误,但奇怪的是,这对clang不起作用,因此我们不得不诉诸-Werror并将所有警告转为错误,这实际上是一个很好的习惯。正如remyabel指出clang我们也可以使用-Werror=implicit-int

答案 1 :(得分:1)

我已经回复了similar question(实际上我很确定它是重复的,但无论如何),答案可以在C99理由中找到。

  

C99的新功能:

     

在C89中,声明中可以省略所有类型说明符   声明中的说明符。在这种情况下,暗示了int。该   委员会认为这一特征的内在危险性超过了   它的便利性,所以它被删除了。效果是保证   生产一种诊断剂,可以捕获另一类   编程错误。发出诊断后,执行   可以选择假设一个隐含的int并继续翻译   程序,以支持利用此功能的现有源代码   特征

@ Shafik的回答告诉你一种方法将警告变为错误(对于Clang)。如果您认为-Werror过于严格,可以使用-Werror=implicit-int将该警告变为错误。在海湾合作委员会中,似乎-pedantic-errors是必要的。

答案 2 :(得分:0)

首先,默认情况下,gcc不是一个符合标准的C编译器。它实现了带有GNU扩展的C89 / C90方言。

您可以使用-std=cNN -pedanticNN可以是909911)使其(尝试)符合指定版本的ISO C标准。 C90允许隐式int;它在C99中被删除了。

但C编译器实际上并不是必需来生成致命的错误消息(#error指令除外)。标准的要求(N1570 5.1.1.3p1)是:

  

符合要求的实施应至少产生一种诊断   消息(以实现定义的方式标识)如果a   预处理翻译单元或翻译单元包含一个   违反任何语法规则或约束,即使行为是   也明确指定为未定义或实现定义。   在其他情况下不需要生成诊断消息。

非致命警告符合&#34;诊断消息&#34;。符合标准的C编译器可以为任何错误打印警告 - 甚至是语法错误 - 然后继续成功编译源文件。 (这是支持某些特定于编译器的语言扩展的方式。)

就个人而言,我发现gcc对某些错误过于宽松;在我看来,缺少int 应该被视为致命错误。但这只是我的偏好,而不是标准规定的要求。

这里的教训是,你不应该认为纯粹的警告是无害的。理想情况下,编译代码应该不会产生任何诊断 。可以忽略警告的情况很少见(但它们确实存在,因为编译器可以自由地警告完全有效的代码)。