2

我目前正在学习和试验 C,并且正在使用Bloodshed 的 DEV-C++作为 IDE。

现在,我刚刚意识到以下代码(因为它是......不包含或什么都没有)编译并运行:

main ()
{
    printf("%d", strlen("hello"));  
}

现在,如果我没记错的话,这个源代码中不应该包含两个头文件以使其正常工作吗? stdio.h并且string.h...但是正如您所看到的,我没有添加它们并且代码仍然编译并成功运行。

我的抱怨是我希望编译器是“严格的”,因为由于我还在学习 C,所以我不希望代码在正常情况下不应该运行。

那么,有什么办法可以防止 Dev-C++ 在涉及到includes 时“纠正我的错误”,即让它更“严格”?

4

3 回答 3

7

C90 有一个特性(没有 C99 和 C++)称为隐式函数声明:当您在函数调用中使用尚未声明的名称时,编译器的行为就像

extern int identifier();

被看见了。该功能已从 C99 中删除,并且大多数编译器甚至在 C99 发布之前都可以选择对此发出警告。

即使住在C90,也不推荐使用这种风格。如果您必须使用此代码维护代码并且无法添加原型,请检查:

  • 函数返回一个 int ( printf 就是这种情况,但有效性取决于 strlen 的实现,它返回一个 size_t 可以是 int 或其他东西)

  • 该函数不是可变参数(strlen 是这种情况,但 printf 不是)

  • 默认情况下不修改参数的类型参数提升(char、short、float 是)并且您必须注意将指针转换为 void* 当预期类型为 void* 时,您必须注意将 NULL 转换为正确的指针类型。(这些与可变参数 BTW 必须注意的事情相同)。

如果不满足这些条件——并且它们不适用于代码中的任何调用——那么你就进入了未定义行为的领域。

于 2009-08-01T11:12:15.770 回答
4

我不知道这是否真的是一个 DevC++ 问题,但无论如何你应该考虑放弃它。它不再被开发并且非常错误。我建议更改为Code::Blocks,它在各个方面都更好,并且允许您使用最新的 GCC 编译器。

于 2009-08-01T10:40:34.117 回答
0

“未定义行为”的一种可能性——如果你在没有可见原型的情况下调用可变参数函数就会得到这种可能性——你的代码可以编译并成功运行。

如果您使用 gcc 作为底层编译器,那么您应该能够传递诸如-std=c89 -pedantic -Wall -Wextra您发布的代码片段之类的标志并获得有关代码的警告。

于 2009-08-01T10:47:59.470 回答