为什么缺少头文件却可以成功编译程序?

发布于 2024-12-09 06:45:22 字数 615 浏览 0 评论 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 编译了它。

I found a weird problem when I was learning the "strtok" function.
At first I missed a header file when writing a demo program as follows:

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

The compiler didn't give any error message and successfully compiled the program. But it lead to a segmentation fault when running. And when I added the missing header file, everything went well.

My question is why the compiler didn't diagnose any errors for the first compilation. I compiled it under Mac OS X with gcc4.2.1.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

相对绾红妆 2024-12-16 06:45:22

在 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*)< 匹配/代码>。

In C, functions were allowed to have no prototypes (declarations). There would be no parameter conversions when calling such functions. Eg.:

f(0);

would call a function named f with a parameter (int)0 even when f was not declared. This results in undefined behavior (...segfaults...) when the actual definition of f (in another .c file, or in a library) was eg. int f(char*) or int f(long). This is not good practice, but is retained for backwards compatibility with original C.

When the prototype is present, the compiler would automatically convert parameter to required types (possibly issuing an error) at call site.

PS: don't get me wrong thinking int is the default. What the compiler actually calls is entirely dependent on the call parameters. Eg. f(1.1) would match with void f(double), f("string") with f(char*).

岁月流歌 2024-12-16 06:45:22

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

因为您没有使用 -Wall - 进行编译韦斯特拉。对于新编写的现代代码,您应该理所当然地这样做。

My question is why the compiler didn't give any error message at the first compilation.

Because you didn't compile with -Wall -Wextra. For newly-written modern code, you should be doing this as a matter of course.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文