0

我在学习“strtok”函数的时候发现了一个奇怪的问题。一开始写demo程序的时候漏掉了一个头文件,如下:

/* 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;
}

编译器没有给出任何错误信息并成功编译了程序。但是在运行时会导致分段错误。当我添加缺少的头文件时,一切都很顺利。

我的问题是为什么编译器在第一次编译时没有诊断出任何错误。我在 Mac OS X 下使用 gcc4.2.1 编译它。

4

2 回答 2

4

在 C 语言中,允许函数没有原型(声明)。调用此类函数时不会进行参数转换。例如。:

f(0);

即使未声明,也会调用以f参数命名的函数。当(在另一个文件或库中)的实际定义是例如时,这会导致未定义的行为(...segfaults...) 。或。这不是好的做法,但为了与原始 C 的向后兼容性而保留。(int)0ff.cint f(char*)int f(long)

当原型存在时,编译器会在调用站点自动将参数转换为所需的类型(可能会发出错误)。

PS:不要误会我的想法int是默认的。编译器实际调用的内容完全取决于调用参数。例如。f(1.1)将匹配void f(double),f("string")f(char*).

于 2011-10-09T10:03:25.230 回答
4

我的问题是为什么编译器在第一次编译时没有给出任何错误消息。

因为你没有用-Wall -Wextra. 对于新编写的现代代码,您应该理所当然地这样做。

于 2011-10-09T10:08:13.727 回答