How do you test if two #define are the same with C preprocessor

I have a C program that has platform-specific definitions for accessing low-level hardware. On some platforms, two macros point to the same variable, while on others they are different:

//Platform_One.h #define FOO_PORT (io.portA) #define BAR_PORT (io.portB) //Platform_Two.h #define FOO_PORT (io.portC) #define BAR_PORT (io.portC) //same 

I have an initializer code that is different from whether #defines are the same or not. Conceptually, I would like the code to look like this:

  callback_struct_t callbacks[] = { #if FOO_PORT == BAR_PORT //unfortunately invalid {&FOO_PORT, handle_foo_bar_func}, #else {&FOO_PORT, handle_foo_func}, {&BAR_PORT, handle_bar_func}, #endif {0,0} }; 

Is there a reliable way to test at compile time if two arbitrary macros have the same definition?

+7
c c-preprocessor
source share
3 answers

You cannot compare preprocessor macros as strings. One possibility would be to put the address of the hardware port (for example, through another macro in the platform headers) in #define , and then compare the addresses.

However, the simplest way would be to compare the addresses in real code, for example:

 if (&FOO_PORT == &BAR_PORT) { // populate callbacks with handle_foo_bar_func } else { // populate callbacks with handle_foo_func and handle_bar_func } 

Until executed in the pre-processor, the compiler can optimize the unused branch, since hardware addresses are likely compile-time constants.

+3
source share

With the gnu c processor, this can be done using the line: https://gcc.gnu.org/onlinedocs/cpp/Stringification.html#Stringification

You can do something like this:

 #include <stdio.h> #include <string.h> #define FOO_PORT (io.portA) #define BAR_PORT (io.portB) //#define FOO_PORT (io.portC) //#define BAR_PORT (io.portC) #define XMACRO_TEST(macro_a, macro_b) MACRO_TEST(macro_a, macro_b) #define MACRO_TEST(macro_a, macro_b) \ if(strcmp((#macro_a),(#macro_b)) == 0) { \ printf(#macro_a" == "#macro_b"\n"); \ } else { \ printf(#macro_a" != "#macro_b"\n"); \ } \ int main(int argc, char *argv[]) { XMACRO_TEST(FOO_PORT, BAR_PORT) return 0; } 
+2
source share

You can compare macros that evaluate to integers. I understand that you have three options:

  • change macro
  • use numeric values ​​for port number macros (are they physical addresses?)
  • Fill the callback structure with code c as one of the sentences

The latter option seems to be the most favorable. When using propper for const, the calculation will be done in most cases during compilation.

+1
source share

All Articles