繁体   English   中英

如何比较两个同名的预处理器宏?

[英]How to compare two preprocessor macros with the same name?

我有一个项目,其中有两个同名的不同预处理器宏,在两个不同的包含文件(来自两个不同的库)中定义,我必须在构建时检查它们是否具有相同的值。

到目前为止,我可以在运行时进行此检查,将宏值分配给不同实现文件中的不同变量,每个变量只包含一个所涉及的头文件。

我怎样才能在构建时做到这一点?

这是我到目前为止所尝试的(其中 Macro1.h 和 Macro2.h 是我无法修改的第三方文件):

头文件:

TestMultiMacros.h:

#ifndef TEST_MULTI_MACROS_H
#define TEST_MULTI_MACROS_H

struct Values
{
    static const unsigned int val1, val2;
    static const unsigned int c1 = 123, c2 = 123;
};

#endif // TEST_MULTI_MACROS_H

宏1.h:

#ifndef MACRO1_H
#define MACRO1_H

#define MY_MACRO 123

#endif // MACRO1_H

宏2.h:

#ifndef MACRO2_H
#define MACRO2_H

#define MY_MACRO 123

#endif // MACRO2_H

实现文件:

TestMultiMacros1.cpp:

#include "TestMultiMacros.h"
#include "Macro1.h"

const unsigned int Values::val1 = MY_MACRO;

TestMultiMacros2.cpp:

#include "TestMultiMacros.h"
#include "Macro2.h"

const unsigned int Values::val2 = MY_MACRO;

入口点.cpp:

#include "TestMultiMacros.h"

using namespace std;

static_assert(Values::val1 == Values::val2, "OK");  // error: expression did not evaluate to a constant
static_assert(Values::c1 == Values::c2, "OK");

int main()
{
}

我会对同时使用 C++11 和 C++17 的解决方案感兴趣。

包括第一个标题。 然后将宏的值保存到constexpr变量中:

constexpr auto foo = MY_MACRO;

然后包含第二个标题。 它应该默默地覆盖MY_MACRO 如果您的编译器开始抱怨, #undef MY_MACRO执行#undef MY_MACRO

然后使用static_assert将宏的新值与变量进行比较:

static_assert(foo == MY_MACRO, "whatever");

这是一个非常简单的 C++17 测试,它通过比较宏扩展的文本来处理任意(非函数)宏。 对于在std::string_view缺少constexpr比较的 c++11,您可以自己编写几行,如本答案所示。

#include <string_view>
#define STRINGIFY(x) STRINGIFY_(x)
#define STRINGIFY_(x) #x

#include "macro1.h"
//#define MY_MACRO A night to remember
constexpr const char* a = STRINGIFY(MY_MACRO);

#undef MY_MACRO
#include "macro2.h"
//#define MY_MACRO A knight to remember
constexpr const char* b = STRINGIFY(MY_MACRO);     

static_assert(std::string_view(a) == b, "Macros differ");

int main() { }

(Godbolt: https ://godbolt.org/z/nH5qVo)

当然,这取决于您所说的宏相等究竟是什么意思。 如果一个头文件有这个版本会报错

#define MY_MACRO (2+2)

另一个有

#define MY_MACRO 4

还值得注意的是,字符串化使空白标准化,但除了修剪末端之外,它不会标准化空白的存在。 所以(2 + 2)(2 + 2)将比较为相等,但不是(2+2)( 2 + 2 )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM