liveBook · Manning

Compound expression

As explained in Modern C, Third Edition

A compound expression is a compiler extension that groups statements and expressions into a single expression whose value is the value of its final expression.

A compound expression is a compiler extension written ({ ... }). It groups statements and expressions into one expression whose value is the final expression, such as (void)0. Unlike a do { ... } while (false) macro, it can appear where an expression is required and can return a value. section 18.4

A value-producing macro

#define MAX_EQSIGN(X, Y) \ ({ \ auto const max_x = (X); \ auto const max_y = (Y); \ (max_x < max_y) ? max_y : max_x; \ }) The final conditional expression supplies the compound expression's value. Capturing X and Y first also evaluates each argument once. section 18.4

Important constraints and behavior:

  • The construct is offered by GCC and related compilers; C23 does not provide a general equivalent. section 18.4
  • Identifiers declared inside remain exposed to surrounding scopes, and goto statements and labels can jump into or out of the construct. section 18.4
 #define SWAP(X, Y)                                              \
   /* This starts the compound expression construct. */          \
   ({                                                            \
     /* These two variables have the role of function            \
        parameters. They ensure to evaluate the                  \
        expression X and Y once, since these could be            \
        complicated lvalue expressions with evaluated            \
        subexpressions that have side effects. */                \
     auto const swap_p1 = &(X);                                  \
     auto const swap_p2 = &(Y);                                  \
     static_assert_compatible(*swap_p1, *swap_p2,                \
                              "to exchange values, '"           \
                              #X "' and '" #Y                   \
                              "' must have compatible types");  \
     auto swap_tmp = *swap_p1;                                   \
     *swap_p1 = *swap_p2;                                        \
     *swap_p2 = swap_tmp;                                        \
     /* ensure that the type of the expression is void */        \
     (void)0;                                                    \
   })

Annotated SWAP expansion showing compound-expression syntax, single evaluation of arguments, type checking, and the final expression value. section 18.4

How Modern C, Third Edition covers it

How deep it goes
Explains syntax, final-value behavior, scope leakage, and goto hazards, but stops short of standardizing the extension.
Examples
Uses SWAP, MAX_EQSIGN, and MAX macros to demonstrate statement grouping, single evaluation, type checking, and value selection.
What it assumes
Assumes familiarity with C macros, expressions, lvalues, and do-while statement macros.
What you can do after
Apply it via GCC-style extensions to write value-producing macros while accounting for evaluation, scope, and portability constraints.
How it connects
Connects compound expressions with macros, do-while constructs, block closures, lambdas, and C23.

This explainer was generated by Manning's knowledge graph from the text of Modern C, Third Edition. The section links point to the parts of the book it draws on.