Search code examples
cgcclinux-kernelmacrosgcc-warning

Compile-time assertion fails without GCC optimization


I have following compile-time assertion which fails if I compile without -O[1-3] flags.

#ifndef __compiletime_error
#define __compiletime_error(message)
#endif
#ifndef __compiletime_error_fallback
#define __compiletime_error_fallback(condition) do { } while (0)
#endif

#define __compiletime_assert(condition, msg, prefix, suffix)        \
    do {                                \
        int __cond = !(condition);              \
        extern void prefix ## suffix(void) __compiletime_error(msg); \
        if (__cond)                     \
            prefix ## suffix();             \
        __compiletime_error_fallback(__cond);           \
    } while (0)

#define _compiletime_assert(condition, msg, prefix, suffix) \
    __compiletime_assert(condition, msg, prefix, suffix)

#define compiletime_assert(condition, msg) \
    _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)

#endif

This would combine with the following macro which is located in another (gcc-4 specific) file:

#define __compiletime_error(message)    __attribute__((error(message)))

the issue comes from this line in the code:

        extern void prefix ## suffix(void) __compiletime_error(msg); \

It seems GCC does not understand extern in the macro without -O[1-3] flag. I am not sure how should I declare __compiletime_error before it actually gets called in this macro. If I remove this line, I get famous warning of Implicit declaration of a function


Solution

  • Your compiletime_assert framework is relying on the optimizer performing dead code elimination to remove the call to prefix ## suffix. This is highly fragile and is in no way guaranteed to work.

    Instead, try using one of the solutions from Ways to ASSERT expressions at build time in C - or, since you're using a modern compiler, just use C11 _Static_assert.