GCC statement expressions & interrupt handler

GCC possède cette extension absolument surprenante qui permet de traiter un bloc — compound statement — entouré de parenthèses comme une expression.

Concrètement, cela permet d'employer des boucles, branchements conditionnels et déclarations au sein d'une expression.

Si l'utilité de la chose n'est pas évidente de premier abord, c'est lors de la définition de macros que cette extension montre tout son potentiel.

Interrupt handler

Une utilisation ingénieuse de cette extension consiste à définir une macro permettant de relancer automatiquement les appels système pouvant être interrompus par un signal.

#define EINTR_HANDLER(x) ({                     \
    typeof(x) result;                           \
    do {                                        \
        result = x;                             \
    } while (result == -1 && errno == EINTR);   \
    result;                                     \
})

Comme le laisse entrevoir le code ci-dessous, la gestion des interruptions s'en trouve grandement simplifiée.

ssize_t readn = EINTR_HANDLER(read(fd, buf, count));

Mais surtout, la gestion des erreurs peut être séparée une fois pour toute de celle des interruptions.