【问题标题】:Can a macro redefinition be applied to single cpp file?可以将宏重新定义应用于单个 cpp 文件吗?
【发布时间】:2016-06-29 19:50:35
【问题描述】:

我正在使用 rapidjson,它是一个全头库。在rapidjson.h,有一个宏RAPIDJSON_ASSERT,在我的一个cpp文件中,我想重新定义它,所以我的文件顶部有这段代码:

#include "stdafx.h" // for windows
#pragma push_macro("RAPIDJSON_ASSERT")
#define RAPIDJSON_ASSERT(x) if(!(x)) throw std::logic_error("rapidjson exception");

#include "rapidjson/rapidjson.h"
#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"

....
....
#pragma pop_macro("RAPIDJSON_ASSERT")

这是rapidjson.h 定义RAPIDJSON_ASSERT 的原因:

#ifndef RAPIDJSON_ASSERT
#include <cassert>
#define RAPIDJSON_ASSERT(x) assert(x)
#endif // RAPIDJSON_ASSERT

文档指出,要覆盖 RAPIDJSON_ASSERT 逻辑,您只需在包含任何文件之前定义 RAPIDJSON_ASSERT

问题是当我在调试器中运行代码时,RAPIDJSON_ASSERT 没有被重新定义。我检查了stdafx.h 是否有任何包含 rapidjson 头文件的内容,但没有任何内容。

我假设每个编译单元都应该运行头文件。

请注意,如果我将宏的重新定义移动到 stdafx.h 中,我会重新定义宏,但我希望能够在每个编译单元中执行此操作。

【问题讨论】:

  • 你在 stdafx.h 中包含 rapidjson 吗?
  • 模式似乎不对。您是想更改该翻译单元的 rapidjson 内部的宏,还是只是在您的翻译单元内部?如果是后者,请将重新定义放在 rapidjson 标头之后。否则,rapidjson 可能会简单地重新定义宏本身
  • @jaggedSpire - 我没有在 stdafx.h 中包含 rapidjson.h,所以我不确定它为什么不会覆盖宏。
  • @KABoissonneault - 我在问题中添加了一些信息。特别是关于 rapidjson.h 是如何定义的。看来您应该在包含宏之前而不是之后定义宏。

标签: c++ macros rapidjson


【解决方案1】:

您似乎想为 rapidjson 代码本身更改 RAPIDJSON_ASSERT 的定义

如果是这样,您需要在定义它的位置之后添加一个#define。除非您想编辑 rapidjson.h 文件,否则唯一的选择是这样做:

#include "stdafx.h" // for windows

// One would assume that the macro gets defined somewhere inside here
#include "rapidjson/rapidjson.h"

// Compiler will complain about macro redefinition without this #undef
#undef RAPIDJSON_ASSERT    
#define RAPIDJSON_ASSERT(x) if(!(x)) throw std::logic_error("rapidjson exception");

#include "rapidjson/document.h"
#include "rapidjson/stringbuffer.h"
#include "rapidjson/writer.h"

现在,其余头文件的 RAPIDJSON_ASSERT 定义已更改。您不需要 push_macro 和 pop_macro 恶作剧 - 宏仅对每个单元有效

请注意,使用#define 重新定义库的内容并不是一件好事

【讨论】:

  • 我在问题中添加了一些信息,但文档指定您应该在包含文件之前定义 RAPIDJSON_ASSERT,而不是之后。没有意义的是,#ifndef 语句 rapidjson.h 似乎在所有编译单元中仅被检查一次。
  • 完全关闭预编译头文件试试?
  • 我认为预编译的标头可能是问题所在。我会试试看。
猜你喜欢
  • 2020-06-22
  • 2010-12-20
  • 2015-07-07
  • 1970-01-01
  • 2020-03-05
  • 1970-01-01
  • 1970-01-01
  • 2019-12-23
  • 1970-01-01
相关资源
最近更新 更多