Search code examples
cgccmacrosc89

Macro: void value not ignored as it ought to be


I'm trying to make a simple assertion macro that returns a boolean, but I keep getting a void function.

#define FALSE 0
#define TRUE !FALSE

#define CASSERT(predicate) \
 ({ \
    if((predicate)) \
    { \
        (TRUE); \
    }else\
    { \
        __debugbreak(); \
       (FALSE); \
    }})

I want to use it like this

if(!CASSERT(X==Y)){}

this is the error I get

error: void value not ignored as it ought to be

error: could not convert '<statement>' from 'void' to 'bool'

I tried a few variations of this code and none of them seems to be working! the output of the CASSERT is a void function!


Solution

  • Perform the text replacement yourself.

    if(!CASSERT(X==Y)){}
    

    Becomes:

    if(!{
        if((X==Y)) {
            (!0);
        }
        else {
            __debugbreak();
            (0);
        }}) {}
    

    Does that look like valid C code? It isn't, because a conditional statement is not an expression returning a boolean.

    You may wish to use a conditional expression with the comma operator to sequence the __debugbreak() and FALSE. Something like:

    #define CASSERT(PRED) ((PRED) ? TRUE : (__debugbreak(), FALSE))
    

    Your code would now expand to:

    if(!((X==Y) ? !0 : (__debugbreak(), 1))) {}
    

    That is valid C code.