In C23, auto declares an object whose type is inferred from its initializer. Thus auto y = 3*x; follows the expression's type instead of requiring a repeated spelling such as float y = 3*x;. section 18.0 section 18.3.1
Use auto when dependent declarations should remain consistent with the expressions that initialize them:
- A generic SWAP macro uses auto const swap_p1 = &(X) and auto const swap_p2 = &(Y) to infer pointers to the operand types. section 18.3.1
- auto swap_tmp = *swap_p1 infers a temporary with the same type as X, avoiding assumptions about the operands' types. section 18.3.1
- The SWAP macro captures each operand once, checks type compatibility, and supports object types other than arrays; auto supplies consistent declarations for each call. section 18.3.1
- C23 also makes it convenient to capture structure results from type-generic library interfaces: auto res = div(x, y); permits access to res.quot and res.rem. section 8.2
Inferring a temporary in SWAP
The essential pattern is auto swap_tmp = *swap_p1;. Because swap_p1 points to the type of X, swap_tmp receives that same inferred type; the declaration remains valid as the macro is applied to different compatible object types. section 18.3.1
#define SWAP(X, Y) \
do { \
/* 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; \
} while (false)
Inspect the complete SWAP fragment, including single-evaluation captures, const-qualified inferred pointers, compatibility checking, and the inferred temporary. section 18.3.1


