C macroevaluate at compile time

advertisements

I need a Macro that would be evaluated at compile time, something like:

#define FIND_RANGE(x) \
if x>16 \
32 \
elif x>8 \
16 \
elif x>4 \
8 \
elif x>2 \
4 \
elif x>1 \
2 \
else \
1 \
endif \

So the code

#define S1 FIND_RANGE(7)
unsinged int i = S1;

would be sent to compiler as

unsinged int i = 8;

Can this simple algorithm be done so it is evaluated at compile time?


While C has no constexpr functions, both GCC and Clang can evaluate simple functions at compile-time with -O1. The related optimization is known as constant folding.

The following C code:

#include <stdio.h>

static inline unsigned int findRange(unsigned int x)
{
    if (x > 16)
        return 32;
    else if (x > 8)
        return 16;
    else if (x > 4)
        return 8;
    else if (x > 2)
        return 4;
    else if (x > 1)
        return 2;
    return 1;
}

int main(void)
{
    unsigned int i = findRange(7);
    printf("%u\n", i);
    return 0;
}

results into x86-64 assembly code (reference: godbolt.org/g/kVYe0u):

main:
        sub     rsp, 8
        mov     esi, 8
        mov     edi, OFFSET FLAT:.LC0
        mov     eax, 0
        call    printf
        mov     eax, 0
        add     rsp, 8
        ret

As you can see, the call to findRange is subsituted by value, which is computed at compile-time.

This works even when findRange is defined as normal (non-inline) function with external linkage.