我正在尝试调试代码块中的头文件。我尝试了一些选项,例如“运行到光标”,并通过在头文件中放置断点,但它并没有在那里停止并通过那里。
如何在其中调试.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库)中定义。编译器将会看到
extern
的printf
声明在读取标头<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/