Shahbaz Shahbaz - 2 years ago 72
C Question

Remove cast from constant in preprocessor


In a microcontroller code, I am using a library provided by the producer where there are many constants defined. I'm trying to give an error if there's a mismatch between some of my constants (shared with components outside the microcontroller, with
) and the microcontroller constants.

For example, the library defines:

#define FLASH_BLOCK_SIZE ((uint8_t)64)
/* else, other models */

And somewhere, in a header shared between the microcontroller code and some code compiled on the PC, I have for example:


And to make sure these constants match, in the microcontroller code, where both constants exist, I have:

#error "mismatch between actual block size and defined block size"

This is to make sure if the code is ever ported to a bigger microcontroller, the shared header would also be updated.

The Problem

The problem is that this gets reduced to:

#if 64 != ((uint8_t)64)

which I'm not sure if is valid C, but nonetheless makes the compiler choke up. Testing, I found out that the problem is not that
is a typedef and it still chokes up with a cast to
for example.

The Question

Is there a way to remove the
part from a value defined as
? If not, is there any way to change it so the expression turns into one without a cast?

I thought about defining
as something and undefining it after the
, but I can't figure out how I can avoid the cast nature of
and turn it into an arithmetic expression.

Answer Source

Here is an improved version (the first version is below). This one does not depend on the cast being uint8_t; it will work with any FLASH_BLOCK_SIZE replacement list of the form ((some type) number).

#define MYPROG_BLOCK_SIZE   64
#define FLASH_BLOCK_SIZE    ((uint8_t)64)

#define B(x)
#define C(x)    B x
#define D(x)    C x

    #error "mismatch between actual block size and defined block size"

Here is the original version:

#define FLASH_BLOCK_SIZE   ((uint8_t)64)

#define uint8_t             
#define Helper(x)          x
#define Deparenthesize(x)  Helper x

#if MYPROG_BLOCK_SIZE != Deparenthesize(Deparenthesize(FLASH_BLOCK_SIZE))
    #error "mismatch between actual block size and defined block size"
#undef uint8_t

When writing code, I would prefer a static assert, but the above does what you requested in the preprocessor.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download