liveBook · Manning

Type inference

As explained in Modern C, Third Edition

Type inference is the compile-time deduction of type information from an expression or declaration without explicitly writing the complete type.

Type inference deduces type information from an expression or declaration at compile time, avoiding the need to write the complete type. In C23, auto, typeof, and typeof_unqual support this technique within type-generic programming. section 18.0 section 18.3

Inferring a declaration

These declarations express the same inferred-versus-explicit intent: `auto y = 3*x;` and `float y = 3*x;`. The first obtains `y`'s type from its initializer; the second states it directly. section 18.3.1

The practical value appears in a generic SWAP macro. `auto const swap_p1 = &(X);` and `auto const swap_p2 = &(Y);` infer pointers to the operand types, while `auto swap_tmp = *swap_p1;` infers the temporary's type from `X`. The macro therefore remains consistent across object types instead of assuming one fixed type. section 18.3.1

Type inference supports generic code while preserving explicit safety checks:

  • Use `auto` when a variable's type should follow its initializer. section 18.3.1
  • Use inferred declarations to maintain type consistency among dependent variables. section 18.5
  • Combine inference with compatibility checks when a generic operation requires related operand types. section 18.3.1
  • Use `typeof` and `typeof_unqual` for type tests or for converting a result expression back to a type determined by macro arguments. section 18.5
 #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 C23 SWAP macro to see inferred pointer declarations, single evaluation of operands, and a compile-time compatibility check working together. section 18.3.1

How Modern C, Third Edition covers it

How deep it goes
Explains C23 inference through declarations and a generic SWAP macro, while only summarizing broader typeof applications.
Examples
Uses inferred declarations, explicit declarations, and a generic SWAP macro with inferred pointers and temporary storage.
What you can do after
Build generic C macros that preserve operand-dependent types and evaluate captured expressions only once.
How it connects
Connects type inference with type-generic programming, generic selection, macros, type compatibility, and anonymous functions.

Also explained in

Compare how 16 books explain type inference →

Related concepts

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.