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

Pie*_*tro 5 c++ compile-time c-preprocessor c++11 c++17

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

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

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

这是我到目前为止所尝试的(其中 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
Run Code Online (Sandbox Code Playgroud)

宏1.h:

#ifndef MACRO1_H
#define MACRO1_H

#define MY_MACRO 123

#endif // MACRO1_H
Run Code Online (Sandbox Code Playgroud)

宏2.h:

#ifndef MACRO2_H
#define MACRO2_H

#define MY_MACRO 123

#endif // MACRO2_H
Run Code Online (Sandbox Code Playgroud)

实现文件:

TestMultiMacros1.cpp:

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

const unsigned int Values::val1 = MY_MACRO;
Run Code Online (Sandbox Code Playgroud)

TestMultiMacros2.cpp:

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

const unsigned int Values::val2 = MY_MACRO;
Run Code Online (Sandbox Code Playgroud)

入口点.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()
{
}
Run Code Online (Sandbox Code Playgroud)

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

Hol*_*Cat 9

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

constexpr auto foo = MY_MACRO;
Run Code Online (Sandbox Code Playgroud)

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

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

static_assert(foo == MY_MACRO, "whatever");
Run Code Online (Sandbox Code Playgroud)

  • *“它应该默默地覆盖 MY_MACRO。如果您的编译器开始抱怨,请先执行#undef MY_MACRO。”*我说您应该始终取消定义第一个宏。如果第二个标头由于某种原因没有定义宏,则静态断言应该无法编译。 (3认同)
  • @Pietro这意味着价值观不同。尝试打印“foo”和“MY_MACRO”。 (2认同)
  • @Pietro 这个答案似乎适用于 Visual C++,因此如果断言对您来说失败,则值会有所不同:https://godbolt.org/z/p7mqQA (2认同)