我目前正在学习和试验C并使用Bloodshed's DEV-C++作为IDE。
现在,我刚刚意识到下面的一段代码(因为它是......不包括或没有)编译并运行:
main ()
{
printf("%d", strlen("hello"));
}
现在,如果我没有弄错的话,不应该在这个源中包含两个头文件以使其工作吗? stdio.h
和string.h
...但正如您所看到的,我没有添加它们,代码仍然编译并成功运行。
我的抱怨是我希望编译器“严格”,因为因为我还在学习C,所以我不希望代码在正常情况下运行。
那么,有没有什么方法可以阻止Dev-C ++在include
s'中纠正我的错误',即让它更加“严格”?
答案 0 :(得分:7)
C90有一个名为(缺少C99和C ++)的函数,称为隐式函数声明:当你在函数调用中使用了尚未声明的名称时,编译器表现得好像
extern int identifier();
已经看到了。该功能已从C99中删除,大多数编译器都可以选择在C99颁布之前就此发出警告。
即使在C90停留,也不建议使用它。如果您必须维护使用此代码并且无法添加原型的代码,请检查:
函数返回一个int(printf是这种情况,但有效性是依赖于strlen的实现,它返回一个size_t,可以是int或其他东西)
该函数不是可变参数(strlen是这种情况,但不是printf)
参数的类型不会被默认参数提升修改(char,short,float are),你必须注意在需要时将指针转换为void *当期望的类型为void *时,你必须注意将NULL转换为正确的指针类型。 (对于可变参数BTW,你必须注意这些事情。)
如果不满足这些条件 - 并且它们不适用于代码中的任何调用 - 则进入未定义行为领域。
答案 1 :(得分:4)
我不知道这实际上是否是DevC ++问题,但无论如何你应该考虑放弃它。它不再被开发,而且非常多。我建议更改为Code::Blocks,这在各方面都更好,并允许您使用最新的GCC编译器。
答案 2 :(得分:0)
“未定义行为”的一种可能性 - 如果你在没有可见原型的情况下调用可变参数函数,你会得到的是你的代码编译并成功运行。
如果您使用gcc作为底层编译器,那么您应该能够传递-std=c89 -pedantic -Wall -Wextra
之类的标记,并获取有关代码的警告,例如您发布的代码段。