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

标签 c header codeblocks

我正在尝试调试代码块中的头文件。我尝试了一些选项,例如“运行到光标”,并通过在头文件中放置断点,但它并没有在那里停止并通过那里。
如何在其中调试.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/

相关文章:

c - 代码没有错误,但程序停止运行

c++ - (C++)Code::Blocks 可能错误的 Qt4 设置

c++ - 带有 VS 调试器的代码块 (IDE)

c - 在 C 中使用库时出错

c - 为什么动态调整字符串会导致崩溃?

c++ - 计算宏函数中可变参数的数量

c++ - 标准::查找 'error no matching function'

java - 如何使用 IBM MQ 在字符串中添加带有(名称和值)的 header

Java native 接口(interface): data type of long integers

c++ - 如何管理多个文件、全局变量和定义