cmacrosc-preprocessor

Can you compare two constant pointers in the C preprocessor?


Say my code looks like this:

gpios.h:

#define GPIO_BASE 0x08000100

#define GPIOA ((GpioRegs *) (GPIO_BASE + 0x04))
#define GPIOB ((GpioRegs *) (GPIO_BASE + 0x0C))
#define GPIOC ((GpioRegs *) (GPIO_BASE + 0x14))

switches.h:

#define SWITCH1_PORT GPIOA    // On this particular system, both switches
#define SWITCH2_PORT GPIOA    // are on the same port. This could change in the future

switches.c:

#if SWITCH1_PORT == SWITCH2_PORT
// Code is a lot simpler if both switches are on the same port
#else
// Otherwise do it the hard way
#endif

SWITCH1_PORT and SWITCH2_PORT are both constants at compile time, so comparing them at compile time should be valid, but in practice I get this error message:

gpios.h:772:45: error: operator '*' has no right operand
  772 | #define GPIOA               ((GpioReg *) (GPIO_BASE + 0x04))
      |                                        ^
switches.h:102:33: note: in expansion of macro 'GPIOA'
  102 | #define SWITCH1_PORT GPIOA
      |                      ^~~~~
switches.c:172:5: note: in expansion of macro 'SWITCH1_PORT'
  172 | #if SWITCH1_PORT  == SWITCH2_PORT
      |     ^~~~~~~~~~~~

I tried casting the pointers to uint32_t, and I tried defining a COMPARE_POINTERS macro, but nothing helped.

Is there a way to do what I want here?


Solution

  • If you expand the macros, you can see why it doesn't work as expected:

    #if ((GpioRegs *) (GPIO_BASE + 0x04)) == ((GpioRegs *) (GPIO_BASE + 0x04))
    

    AFAIK, you can't do type-casts inside of an #if. You are likely going to have to make a different set of macros that resolve to integers instead of pointers, eg:

    gpios.h:

    #define GPIO_BASE 0x08000100
    
    #define GPIOA_INT (GPIO_BASE + 0x04)
    #define GPIOB_INT (GPIO_BASE + 0x0C)
    #define GPIOC_INT (GPIO_BASE + 0x14)
    
    #define GPIOA ((GpioRegs *) GPIOA_INT)
    #define GPIOB ((GpioRegs *) GPIOB_INT)
    #define GPIOC ((GpioRegs *) GPIOC_INT)
    

    switches.h:

    #define SWITCH1_PORT_INT GPIOA_INT
    #define SWITCH2_PORT_INT GPIOA_INT
    
    #define SWITCH1_PORT GPIOA
    #define SWITCH2_PORT GPIOA    
    

    switches.c:

    #if SWITCH1_PORT_INT == SWITCH2_PORT_INT
    // Code is a lot simpler if both switches are on the same port
    #else
    // Otherwise do it the hard way
    #endif