gpt4 book ai didi

c - 为什么包含使用完整路径的 header 会导致更好的错误消息?

转载 作者:太空狗 更新时间:2023-10-29 16:38:45 25 4
gpt4 key购买 nike

最近有一篇关于 Ask Ubuntu 的帖子,OP 试图编译一个包含 term.h 的程序.当代码有 #include <term.h> ,错误是:

In file included from clear_screen_UNIX.c:5:0:
clear_screen_UNIX.c:9:6: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘->’ token
void clear_screen(void) {
^
clear_screen_UNIX.c: In function ‘main’:
clear_screen_UNIX.c:23:14: error: called object is not a function or function pointer
clear_screen();
^
clear_screen_UNIX.c:26:14: error: called object is not a function or function pointer
clear_screen();

然后 OP 包含了到 term.h 的完整路径( #include "/usr/include/term.h" ),这导致了更有用的消息:

In file included from clear_screen_UNIX.c:7:0:
/usr/include/term.h:125:21: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘->’ token
#define CUR cur_term->type.
^
/usr/include/term.h:202:40: note: in expansion of macro ‘CUR’
#define clear_screen CUR Strings[5]
^
clear_screen_UNIX.c:9:6: note: in expansion of macro ‘clear_screen’
void clear_screen(void) {
^
clear_screen_UNIX.c: In function ‘main’:
clear_screen_UNIX.c:23:14: error: called object is not a function or function pointer
clear_screen();
^
clear_screen_UNIX.c:26:14: error: called object is not a function or function pointer
clear_screen();

这些消息清楚地表明问题是由于宏扩展引起的。

我自己也验证了结果。我想知道为什么 GCC 在给出完整路径时会产生更好的错误。我可以让它生成与系统包含语法相似的消息吗?

我使用的是 GCC 4.9.2,我怀疑 OP 使用的是 GCC 4.8.2(考虑到 Ubuntu 的版本)。

最佳答案

结论

如果给出 header 的完整路径,GCC 会给出不同/更好消息的原因是 GCC 预处理器将信息提供给 GCC 的 cc1。预处理器生成的 .i 的注释行末尾的一些数字表明包含的头文件是系统头文件或本地头文件。文件。

然后 cc1根据 GCC documentation,如果头文件是本地头文件,编译器将生成更多有用的消息,如果头文件是系统头文件,编译器将抑制一些错误消息。 .

要使正常版本的代码输出错误消息就像指定头文件完整路径的代码一样,正如您所要求的,GCC 需要通过指定选项 -nostdinc 来停止包含所有系统目录。 , 然后使用 -I 显式告诉 GCC 它可以搜索头文件的目录而不将该目录视为系统目录旗帜。

对于您的代码,命令行可能如下所示(GCC_INCLUDE_DIR 是您的默认 GCC 包含目录,对于系统默认 GCC,它可能是 /usr/lib/gcc/x86_64-unknown-linux-gnu/4.9.2/include/):

gcc -c t.c -nostdinc -I/usr/include/ -IGCC_INCLUDE_DIR

源代码

将源代码从 this original post 移至此处使这个答案更有帮助。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <term.h>

//#include "/usr/include/term.h"

void clear_screen(void) {
if (!cur_term) {
int result;
setupterm( NULL, STDOUT_FILENO, &result );
if (result <= 0)
return;
}

putp( tigetstr( "clear" ) );
}

int main(void) {
puts("I am going to clear the screen");
sleep(1);
clear_screen();
puts("Screen Cleared");
sleep(1);
clear_screen();

return 0;

}

预处理器生成文件的区别

您可以使用以下命令行要求 GCC 输出预处理器生成的代码。此代码将被输入到 GCC 的实际编译器中,cc1 .如果预处理器生成的文件完全相同,则 cc1编译器的行为应该完全相同。 (假设代码被放入文件 t.c )

 gcc -E t.c -o t.i

以下是两个gcc预处理器生成的区别.i文件。 t.fullpath.i是用全路径头文件生成的文件,而t.i是没有完整路径的代码(一些 diff 输出已被删除,因为它们只是文件名差异。)

$ diff t.i t.fullpath.i
2920,2922c2920,2924
< # 1 "/usr/include/term.h" 1 3 4
< # 47 "/usr/include/term.h" 3 4
---
> # 1 "/usr/include/term.h" 1
> # 47 "/usr/include/term.h"
2924,2925c2926,2927
< # 48 "/usr/include/term.h" 2 3 4
< # 80 "/usr/include/term.h" 3 4
---
> # 48 "/usr/include/term.h" 2
> # 80 "/usr/include/term.h"
3007,3008c3009,3010
< # 81 "/usr/include/term.h" 2 3 4
< # 673 "/usr/include/term.h" 3 4
---
> # 81 "/usr/include/term.h" 2
> # 673 "/usr/include/term.h"
3041c3043
< # 729 "/usr/include/term.h" 3 4
---
> # 729 "/usr/include/term.h"
预处理器生成的代码注释中的不同标志会有所不同

海湾合作委员会的 cc1编译器将利用预处理器生成的信息生成错误信息的源代码位置,以及将来用于 gdb 的调试信息。

对于以下格式:

# line-number "source-file" [flags]

数字34标志的含义:

  • 3: 以下文本来自系统头文件( #include <>#include "" )
  • 4:以下文本应被视为包含在隐式 extern "C" 中 block 。

    有关这些标志的不同种类的更多信息,请参阅 this link .

因此,对于没有完全指定路径的代码,cc1编译器会把它当作一个系统头文件,并假定系统代码大部分是正确的,然后只输出用户代码的错误信息。这就是错误消息较短的原因。

关于c - 为什么包含使用完整路径的 header 会导致更好的错误消息?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29736949/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com