当我学习“strtok”功能时,我发现了一个奇怪的问题。 起初我在编写演示程序时错过了一个头文件,如下所示:
/* strtok example */
#include <stdio.h>
//#include <string.h> // the header file I've missed at first
int main ()
{
char str[] ="- This, a sample string.";
char * pch;
printf ("Splitting string \"%s\" into tokens:\n",str);
pch = strtok (str," ,.-");
while (pch != NULL)
{
printf ("%s\n",pch);
pch = strtok (NULL, " ,.-");
}
return 0;
}
编译器没有给出任何错误消息并成功编译了程序。但它在运行时会导致分段错误。当我添加丢失的头文件时,一切都进展顺利。
我的问题是为什么编译器没有诊断第一次编译的任何错误。我使用gcc4.2.1在Mac OS X下编译它。
答案 0 :(得分:4)
在C中,允许函数没有原型(声明)。调用这些函数时不会有参数转换。例如:
f(0);
即使未声明f
,也会使用参数(int)0
调用名为f
的函数。当f
(在另一个.c
文件中或在库中)的实际定义是例如时,这会导致未定义的行为(...段错误...)。 int f(char*)
或int f(long)
。这不是一种好的做法,但保留了与原始C的向后兼容性。
当原型出现时,编译器会在调用站点自动将参数转换为所需类型(可能发出错误)。
PS:不要错误地认为int
是默认值。编译器实际调用的内容完全取决于调用参数。例如。 f(1.1)
与void f(double)
匹配,f("string")
与f(char*)
匹配。
答案 1 :(得分:4)
我的问题是为什么编译器在第一次编译时没有给出任何错误信息。
因为您没有使用-Wall -Wextra
进行编译。对于新编写的现代代码,您当然应该这样做。