如何在C中识别重新定义的宏?

时间:2010-06-22 09:47:48

标签: c c-preprocessor

我有两个大型框架库,其头文件包含在我的项目中。任何一个都可以完美地工作,但包括两者都会导致不稳定的行为(但没有与宏相关的错误消息)。

我认为他们都#define一个同名的宏。识别有问题的宏的最有效方法是什么?

6 个答案:

答案 0 :(得分:5)

  

我认为他们都#define一个同名的宏。

这应该至少产生编译器的警告(如果它们在同一个翻译单元中)。

  

如何在C / C ++中识别重新定义的宏?

据我所知,没有直截了当的方式。

  

任何一个都可以完美地运作,但包括两者都会导致不稳定的行为

你能否告诉我们一些有关古怪行为的细节?究竟发生了什么?是什么让你认为这是宏观定义?

答案 1 :(得分:3)

如果头文件编写错误并且#undef SYMBOL ... #define SYMBOL something-else则无法跟踪此信息。只需#defining一次宏两次至少应该发出警告。你必须更仔细地研究'不稳定的行为'。

答案 2 :(得分:3)

尝试查看预处理的输出,以便在#include头文件时以及不执行时确定它的不同之处。使用gcc和MSVC,您可以使用-E进行编译,以将预处理器输出打印到stdout。 (它可能会有数千行,因此您需要将其传输到文件中。)

答案 3 :(得分:2)

您应该可以在源代码上运行ctagsctags可以生成一个标记文件,其中包含C文件中宏的名称和位置。

您可以使用--c-kinds选项控制ctags将在标记文件中存储的符号类型。 例如。 ctags --c-kinds=+d -f tags --recurse ./your_source_directory/

然后,您可以在结果标记文件中搜索重复项。

答案 4 :(得分:1)

grep for #define?

你确定问题不是宏(例如结构包装的pragma,全局内存分配器,类名的全局命名空间,搞乱语言环境......)

答案 5 :(得分:1)

  1. 编译所有警告 - 他们应该告诉你何时已经定义了一个宏'(也许你可以修改代码以解决这个问题)
  2. 如果(1)没有帮助,那么你应该尝试为每个库创建函数包装器。这样,您可以通过使用包装函数包含包装的标头来避免包含冲突的标头。这很费力,但它有时是使两个库在应用程序中共存的唯一方法。
  3. 基本上,解决方案(2)会在库之间进行分离。当强制使用使用不同选项编译的预编译库(一个库Unicode和另一个ASCII)时,此类冲突的示例是ACEwxWidgets(2.8版本)。