2

我有一个需要修改和运行的 C 项目。在某个时候,在我的源文件中

#ifndef THE_FLAG
// declare important stuff
#endif

但是,我不知道d 来自THE_FLAG哪里。#include没有在我的项目中定义,它隐藏在外部库的某个地方。

我试过gcc -M了,但它显示了标题,如果它直接包含在包含层次结构中的更高位置,则没有信息。

该项目过于复杂,无法手动跟踪所有依赖项。它是用./configure && make.

问题:如何跟踪这种外部依赖?

4

3 回答 3

4

尝试使用gcc -E. 这将告诉 gcc 在预处理阶段停止。作为其中的一部分,它会告诉你所有的#defines 来自哪里。

请注意,这将创建一个文本文件,而不是.o文件。

于 2013-01-08T09:50:57.613 回答
2

您可以让 gcc 准确地告诉您标志的定义位置,方法是重新定义它以用于测试目的,例如

#include <limits.h>

#define INT_MAX 42

int f(void)
{
        return INT_MAX;
}

会让 gcc 抱怨

main.c:4:0: warning: "INT_MAX" redefined [enabled by default]
 #define INT_MAX 42
 ^
In file included from main.c:2:0:
/usr/lib/gcc/x86_64-redhat-linux/4.8.1/include/limits.h:120:0: note: this is the location of the previous definition
 #define INT_MAX __INT_MAX__
 ^

同样的策略也适用于查找结构定义(如果您有多个架构师特定的头文件并且您不确定实际使用哪个头文件,这非常有用!)。

#include <stdio.h>

typedef void FILE;

void f(void)
{
}

main.c:3:14: error: conflicting types for ‘FILE’
 typedef void FILE;
              ^
In file included from main.c:1:0:
/usr/include/stdio.h:48:25: note: previous declaration of ‘FILE’ was here
 typedef struct _IO_FILE FILE;
                         ^
于 2013-09-05T07:10:25.360 回答
0

gcc -E会给我们预处理后的输出。但有时开发人员很难验证.c文件是否很大并且包含一些大的头文件。在这种情况下,检查构建输出会更容易。#warning将在编译期间将消息打印为警告。

#ifndef THE_FLAG
#warning "including ABC stuff"
// declare important stuff
#endif

我们也可以使用编译器警告#pragma,但它不是独立于平台的。

#pragma "including ABC stuff"

如果我们想在某处定义了一些不需要的宏时停止编译,我们可以使用#error.

#ifdef UNWANTED_FLAG
#error "Build stopped. UNWANTED flag has been defined"
#endif
于 2013-01-08T11:03:31.417 回答