Search code examples
cmacroscomma-operator

What's the syntax of following c define?


Following snippet is from mac sdk signal.h:

#define sigemptyset(set)    (*(set) = 0, 0)

just wonder what does , 0) do?


Solution

  • The macro expands to a comma expression: the left operand, evaluated first, sets the object pointed to by set to 0, then the right operand is evaluated and its value is the value of the whole expression, hence: 0.

    In other words, the macro behaves like a function that always succeeds, success indicated by the return value 0.

    Except for the type checking, the macro is equivalent to:

    #include <signal.h>
    
    int sigemptyset(sigset_t *set) {
        *set = 0;
        return 0;
    }
    

    Note that the <signal.h> header file also contains a prototype for this function:

    int sigemptyset(sigset_t *);
    

    In your code, a call sigemptyset(&sigset) invokes the macro, but you can force a reference to the library function by writing (sigemptyset)(&sigset) or by taking a pointer to the function. The macro allows for inline expansion without a change of prototype. clang can perform inline expansion at link time for small functions, but not for functions defined inside dynamic libraries.

    The same trick is used for other functions in the header file, for which the , 0) is necessary for the expression to evaluate to 0 with type int:

    #define sigaddset(set, signo)   (*(set) |= __sigbits(signo), 0)
    #define sigdelset(set, signo)   (*(set) &= ~__sigbits(signo), 0)
    #define sigemptyset(set)        (*(set) = 0, 0)
    #define sigfillset(set)         (*(set) = ~(sigset_t)0, 0)