gpt4 book ai didi

c - 在代码块中调试头文件

转载 作者:行者123 更新时间:2023-11-30 15:23:47 29 4
gpt4 key购买 nike

我正在尝试调试代码块中的头文件。我尝试了一些选项,例如“运行到光标”,并通过在头文件中放置断点,但它并没有在那里停止并通过那里。
如何在其中调试.h文件?
如果您需要任何信息,请发表评论。我将提供信息。

最佳答案

调试器在编译后执行程序(并且编译器已经
指示将调试信息插入已编译的程序中。它可以让您暂停
在您在代码中设置的断点处执行,但是只有在以下情况下它才能在断点处暂停
您已在程序运行时到达的可执行代码行中设置了断点。
如果在不是可执行代码的某行或在可执行代码的某行设置断点
但是程序永远不会到达,那么调试器永远不会到达该断点。

查看这个玩具C程序,并考虑可能在其中设置A,...,I的每个位置
Code :: Blocks中的断点:

foo.h

#ifndef FOO_H
#define FOO_H

#define FORTY_TWO 42 /* A */
extern void the_answer_is(void); /*B*/

#endif


foo.c

#include "foo.h" /* C */
#include <stdio.h>

static int forty_two = FORTY_TWO; /* D */

void the_answer_is(void) /* E */
{
int i = forty_two; /* F */
printf("The answer is...%d\n",i); /* G */
}


main.c

#include "foo.h"

int main(void) /* H */
{
the_answer_is(); /* I */
return 0;
}


A的断点?

这是一个预处理程序指令。预处理器将其从源中删除
代码到达编译器之前。因此,编译器永远不会看到它。所以
调试器对此一无所知。这里没有可执行代码。断点
永远不会达到。

B的断点?

这是一个外部函数声明。它提供了必要的信息
编译器和链接器。但这不是可执行代码。
extern void the_answer_is(void);不是您的程序可以执行的操作。
永远不会达到此断点。

在C的断点?

除了预处理器删除了A之外,这里的故事与A相同。
#include指令并将其替换为以下内容的(预处理)内容
foo.h。这断点将永远不会达到。

断点d?

这行是全局静态初始化。它是在编译时完成的,
在程序运行之前。没有可执行代码。永远不会达到此断点。

E的断点?

该行是函数入口,从函数定义开始。
它本身不是可执行代码,但它是某些代码的入口
可执行代码。因此可以在此处达到断点。调试器将
只是“超调”一点,然后停在
函数定义。如果函数 the_answer_is,您的程序将在此处到达断点。
在执行的某个时刻被调用。

F的断点?

该行定义并初始化 int i。这里的断点将是
在与E相同的情况下达到的位置,这是调试器所在的位置
实际上会停在E处的断点。

G的断点?

最有趣的一个。该行是对以下函数的调用:
在外部库(标准C库)中定义。编译器将会看到
externprintf声明在读取标头 <stdio.h>
如果您打开了 stdio.h并在 extern处设置了断点
printf的声明,它将永远无法到达(与B相同)。但
在这里,我们有一个呼叫 printf,并且可以在
与E和F相同的情况。

因此可以达到此断点。但假设您达到了目标
然后想进入调试器中对 printf的此调用。您
将无法。调试器将跳过它。你的程序
已使用调试信息进行编译,但是其中包含的库
printf被定义没有。您根本不编译该库;你刚才
将其与您的程序链接。如果没有调试有关该库的信息,
并访问其源代码,调试器无法介入其中;所以
没有。

您可能会觉得,如果您可以“进入”
<stdio.h>这样的标题,您会找到
在那里声明的库函数,例如 printf,您可以
调试它。你不会在那里找到源代码。你会发现的是
外部声明:

extern int printf( const char* format, ... );


<stdio.h>对您的编译器的作用只是告知其名称
stdio库函数的名称以及应如何调用它们。然后
它可以告诉您是否调用未声明的函数或调用它
以错误的方式。它不需要 printf的源代码,因为它已经在
标准C库,你的程序会自动连接。

断点H +

这是整个程序的入口点,所以这个断点
总是会达到,除非灾难性事故。就像
E,调试器将在下一个可执行行停止。

我的断点?

就像H一样,始终会到达对 the_answer_is的调用。
而且因为我们现在知道 the_answer_is被调用,所以我们也知道
将达到断点E,F和G。

底线:


将断点放在 #include指令中是没有意义的
或任何其他预处理程序指令。编译器永远不会看到它们。
调试器对此一无所知。
通常,在C语言中,将断点放在标头中毫无意义
文件,因为它们只包含声明和预处理器
指令,而不是可执行代码。 (在C ++中,情况完全不同。
C ++头文件通常包含可执行代码,您可以放置​​断点
在他们之中。)

关于c - 在代码块中调试头文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28650353/

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