Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to compare two preprocessor macros with the same name?

I have a project where there are two different preprocessor macros with the same name, defined in two different include files (from two different libraries), and I have to check if they have the same value at build time.

So far I could make this check at run time, assigning the macro values to different variables in different implementation files, each including only one of the headers involved.

How can I do it at build time?

This is what I tried so far (where Macro1.h and Macro2.h are third-party files I cannot modify):

Header files:

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

Macro1.h:

#ifndef MACRO1_H
#define MACRO1_H

#define MY_MACRO 123

#endif // MACRO1_H

Macro2.h:

#ifndef MACRO2_H
#define MACRO2_H

#define MY_MACRO 123

#endif // MACRO2_H

Implementation files:

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;

entrypoint.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()
{
}

I would be interested in a solution using both C++11 and C++17.

like image 490
Pietro Avatar asked Feb 13 '20 10:02

Pietro


1 Answers

Include the first header. Then save the value of the macro to a constexpr variable:

constexpr auto foo = MY_MACRO;

Then include the second header. It should silently override MY_MACRO. If your compiler starts complaining, do #undef MY_MACRO first.

Then compare the new value of the macro with the variable using a static_assert:

static_assert(foo == MY_MACRO, "whatever");
like image 167
HolyBlackCat Avatar answered Sep 22 '22 23:09

HolyBlackCat