如何从C中的包含文件中追踪缺少结构的原因?

时间:2009-07-01 05:08:15

标签: c struct header

我有一个相当大的项目我正在移植,并且在其中一个MANY标题中,我包含了一个包含pmc_mdep结构定义的文件。 (在它刚刚声明的文件中,但后来实际定义了它。)

尝试编译它会让我错误地认为该结构是一个不完整的类型(我相信这意味着它缺乏定义)。

当我在这个项目上运行预处理器时,它确实包含了该文件,但预处理器输出没有结构定义(但确实包含该文件中的枚举)。

有没有一种方法可以找出为什么某些头文件会进入预处理器输出,有些则没有?

TIA

(另外,这不是唯一的编译错误,端口已经完成了一半,但它应该至少超过这部分)

6 个答案:

答案 0 :(得分:2)

我通常只是从结构中追溯,找到预处理器将遇到的所有封闭的"#ifdef""#if"行,并查看哪一行控制从输入流中删除结构到编译器。

除了最毛茸茸的头文件(即那些具有大量嵌套条件编译语句的文件)之外,它通常可以很快地运行。对于那些,我通常会查看预处理器输出,以识别头文件中的最后一行,使其成为编译器输入流。

几乎可以肯定,下一行将是一个条件编译语句,你没有满足包含条件。

例如,如果this是头文件,则需要回过头来查看应该定义_KERNEL以获取声明和定义。

答案 1 :(得分:1)

我不敢;您将不得不寻找围绕您感兴趣的区域的#ifdef,并找出未定义这些符号的原因。如果它正在移植到Linux / UNIX并且您缺少标准头文件中的内容,则可能未在Makefile或config.h中定义正确的_XOPEN_SOURCE或_BSD_SOURCE。

答案 2 :(得分:1)

最可能的原因是定义周围有一个#define。由于相应的符号未被定义或定义为某个其他值,因此即使包括头部本身,也不包括该定义。你必须手动检查它。

答案 3 :(得分:1)

Raymond Chen对此有一个blog post

  

你可能会发现自己处于#ifdef s曲折的迷宫中。或者您可能想知道为什么您的宏不起作用。

     
    

我的头文件中有这些行:

#define MM_BUSY     0x0001
#define MM_IDLE     0x0002
         

但是当我尝试使用它们时,我会遇到错误。

sample.cpp(23): error C2065: 'MM_BUSY': undeclared identifier
sample.cpp(40): error C2065: 'MM_IDLE': undeclared identifier
         

知道为什么会这样吗?

  

解决方案:使用#error跟踪问题的方式与分散printf周围跟踪常规错误的方式相同。

来源: Use the #error directive to check whether the compiler even sees you

答案 4 :(得分:1)

我认为除了检查预处理器输出以了解为什么包含一个文件之外,还有更好的方法。 Here是gcc的预处理器输出格式,可以帮助您理解预处理器的输出。

另外,您可以尝试比较正在移植的输出与现有输出之间的输出。

答案 5 :(得分:1)

你说:

  

我有一个相当大的项目我正在移植,并且在其中一个MANY标题中,我包含了一个包含pmc_mdep结构定义的文件。 (之前在刚刚声明的文件中,但后来实际定义了它。)

     

尝试编译它会让我错误地认为该结构是一个不完整的类型(我相信这意味着它缺乏定义)。

如果在完全定义pmc_mdep之前尝试将pmc_mdep嵌入到其他结构中,则会发生此错误。请注意,您可以将指向不完整类型的指针嵌入到结构中,但不能将不完整类型的实际实例嵌入。

您还讨论了在应该定义结构的文件上运行预处理器,并且您看到枚举形成标题,但不是结构定义。这表明你可能有一个错误的注释,无意中删除了结构,或者你可能在#ifdef XXX#endif之间嵌入了结构定义,但是在编译时没有定义XXX 。它甚至可能是#if 0

我只在包含结构定义的标题上运行C预处理器,以查看它产生的内容;它比试图查看整个程序(源文件)的输出要短。如果我不能迅速发现问题,我会用杂散的枚举标记部分,以查看哪些部分可以通过,哪些部分不通过。