liveBook · Manning

Type-generic macro

As explained in Modern C

A type-generic macro interface is a macro-based C interface that selects type-specific operations for its arguments.

A type-generic macro presents one C interface while selecting a type-specific operation for its arguments. Mathematical calls such as sin(x), pow(x, n), and fabs(x) can therefore use the argument type to choose an appropriate function. section 8.2

Dispatching fabs

#define fabs(X) \ _Generic((X), \ float: fabsf, \ long double: fabsl, \ default: fabs)(X) _Generic selects a function pointer from the controlling expression's type; the selected function is then applied to X. float chooses fabsf, long double chooses fabsl, and other arithmetic types use fabs. TAKEAWAY: _Generic is not itself a macro feature, but it becomes a type-generic interface when embedded in a macro expansion. section 16.6

A practical interface can extend the same pattern:

  • Define type-specific inline functions, then dispatch to them through function pointers. section 16.6
  • For a two-argument operation such as minimum, use (A)+(B) as the controlling expression so arithmetic conversions determine the selected type. section 16.6
  • Account for promotions when classifying narrow integer expressions; arithmetic operations commonly promote them to signed or unsigned integer types. section 16.6
  • Prefer established mathematical implementations rather than replacing them with handcrafted code, because implementations may use processor-specific instructions and controlled numerical precision. section 8.2
1   _Generic(controlling expression,
2     type1: expression1,
3     ... ,
4     typeN: expressionN)


!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":0},{\"line\":0,\"ch\":1}],[{\"line\":1,\"ch\":10},{\"line\":1,\"ch\":11}],[{\"line\":0,\"ch\":4},{\"line\":0,\"ch\":12}],[{\"line\":1,\"ch\":0},{\"line\":1,\"ch\":1}],[{\"line\":2,\"ch\":0},{\"line\":2,\"ch\":1}],[{\"line\":3,\"ch\":0},{\"line\":3,\"ch\":1}]]"}
!@%STYLE%@!

Use the syntax listing to inspect the controlling expression, type associations, selected expressions, and optional default case. section 16.6

 7   inline
 8   double min(double a, double b) {
 9     return a < b ? a : b;
10   }
11
12   inline
13   long double minl(long double a, long double b) {
14     return a < b ? a : b;
15   }
16
17   inline
18   float minf(float a, float b) {
19     return a < b ? a : b;
20   }
21
22   /**
23    ** @brief Type-generic minimum for floating-point values 
24    **/ 
25   #define min(A, B)                               \
26   _Generic((A)+(B),                               \
27            float: minf,                           \
28            long double: minl,                     \
29            default: min)((A), (B))


!@%STYLE%@!
{"css":"{\"css\": \"font-weight: bold;\"}","target":"[[{\"line\":0,\"ch\":1},{\"line\":0,\"ch\":2}],[{\"line\":10,\"ch\":1},{\"line\":10,\"ch\":2}],[{\"line\":20,\"ch\":1},{\"line\":20,\"ch\":2}],[{\"line\":0,\"ch\":5},{\"line\":0,\"ch\":11}],[{\"line\":5,\"ch\":5},{\"line\":5,\"ch\":11}],[{\"line\":10,\"ch\":5},{\"line\":10,\"ch\":11}],[{\"line\":1,\"ch\":1},{\"line\":1,\"ch\":2}],[{\"line\":11,\"ch\":1},{\"line\":11,\"ch\":2}],[{\"line\":21,\"ch\":1},{\"line\":21,\"ch\":2}],[{\"line\":1,\"ch\":5},{\"line\":1,\"ch\":11}],[{\"line\":6,\"ch\":10},{\"line\":6,\"ch\":16}],[{\"line\":21,\"ch\":19},{\"line\":21,\"ch\":25}],[{\"line\":1,\"ch\":5},{\"line\":1,\"ch\":11}],[{\"line\":6,\"ch\":10},{\"line\":6,\"ch\":16}],[{\"line\":21,\"ch\":19},{\"line\":21,\"ch\":25}],[{\"line\":1,\"ch\":5},{\"line\":1,\"ch\":11}],[{\"line\":6,\"ch\":10},{\"line\":6,\"ch\":16}],[{\"line\":21,\"ch\":19},{\"line\":21,\"ch\":25}],[{\"line\":2,\"ch\":1},{\"line\":2,\"ch\":2}],[{\"line\":12,\"ch\":1},{\"line\":12,\"ch\":2}],[{\"line\":22,\"ch\":1},{\"line\":22,\"ch\":2}],[{\"line\":2,\"ch\":7},{\"line\":2,\"ch\":13}],[{\"line\":7,\"ch\":7},{\"line\":7,\"ch\":13}],[{\"line\":12,\"ch\":7},{\"line\":12,\"ch\":13}],[{\"line\":3,\"ch\":0},{\"line\":3,\"ch\":2}],[{\"line\":4,\"ch\":0},{\"line\":4,\"ch\":2}],[{\"line\":5,\"ch\":0},{\"line\":5,\"ch\":2}],[{\"line\":0,\"ch\":5},{\"line\":0,\"ch\":11}],[{\"line\":5,\"ch\":5},{\"line\":5,\"ch\":11}],[{\"line\":10,\"ch\":5},{\"line\":10,\"ch\":11}],[{\"line\":6,\"ch\":0},{\"line\":6,\"ch\":2}],[{\"line\":6,\"ch\":5},{\"line\":6,\"ch\":16}],[{\"line\":21,\"ch\":14},{\"line\":21,\"ch\":25}],[{\"line\":6,\"ch\":5},{\"line\":6,\"ch\":16}],[{\"line\":21,\"ch\":14},{\"line\":21,\"ch\":25}],[{\"line\":6,\"ch\":5},{\"line\":6,\"ch\":16}],[{\"line\":21,\"ch\":14},{\"line\":21,\"ch\":25}],[{\"line\":7,\"ch\":0},{\"line\":7,\"ch\":2}],[{\"line\":2,\"ch\":7},{\"line\":2,\"ch\":13}],[{\"line\":7,\"ch\":7},{\"line\":7,\"ch\":13}],[{\"line\":12,\"ch\":7},{\"line\":12,\"ch\":13}],[{\"line\":8,\"ch\":0},{\"line\":8,\"ch\":2}],[{\"line\":9,\"ch\":0},{\"line\":9,\"ch\":2}],[{\"line\":10,\"ch\":0},{\"line\":10,\"ch\":2}],[{\"line\":0,\"ch\":5},{\"line\":0,\"ch\":11}],[{\"line\":5,\"ch\":5},{\"line\":5,\"ch\":11}],[{\"line\":10,\"ch\":5},{\"line\":10,\"ch\":11}],[{\"line\":11,\"ch\":0},{\"line\":11,\"ch\":2}],[{\"line\":11,\"ch\":5},{\"line\":11,\"ch\":10}],[{\"line\":16,\"ch\":41},{\"line\":16,\"ch\":46}],[{\"line\":20,\"ch\":14},{\"line\":20,\"ch\":19}],[{\"line\":11,\"ch\":5},{\"line\":11,\"ch\":10}],[{\"line\":16,\"ch\":41},{\"line\":16,\"ch\":46}],[{\"line\":20,\"ch\":14},{\"line\":20,\"ch\":19}],[{\"line\":11,\"ch\":5},{\"line\":11,\"ch\":10}],[{\"line\":16,\"ch\":41},{\"line\":16,\"ch\":46}],[{\"line\":20,\"ch\":14},{\"line\":20,\"ch\":19}],[{\"line\":12,\"ch\":0},{\"line\":12,\"ch\":2}],[{\"line\":2,\"ch\":7},{\"line\":2,\"ch\":13}],[{\"line\":7,\"ch\":7},{\"line\":7,\"ch\":13}],[{\"line\":12,\"ch\":7},{\"line\":12,\"ch\":13}],[{\"line\":13,\"ch\":0},{\"line\":13,\"ch\":2}],[{\"line\":14,\"ch\":0},{\"line\":14,\"ch\":2}],[{\"line\":15,\"ch\":0},{\"line\":15,\"ch\":2}],[{\"line\":16,\"ch\":0},{\"line\":16,\"ch\":2}],[{\"line\":17,\"ch\":0},{\"line\":17,\"ch\":2}],[{\"line\":18,\"ch\":0},{\"line\":18,\"ch\":2}],[{\"line\":18,\"ch\":5},{\"line\":18,\"ch\":12}],[{\"line\":19,\"ch\":0},{\"line\":19,\"ch\":2}],[{\"line\":19,\"ch\":5},{\"line\":19,\"ch\":13}],[{\"line\":20,\"ch\":0},{\"line\":20,\"ch\":2}],[{\"line\":11,\"ch\":5},{\"line\":11,\"ch\":10}],[{\"line\":16,\"ch\":41},{\"line\":16,\"ch\":46}],[{\"line\":20,\"ch\":14},{\"line\":20,\"ch\":19}],[{\"line\":21,\"ch\":0},{\"line\":21,\"ch\":2}],[{\"line\":6,\"ch\":5},{\"line\":6,\"ch\":16}],[{\"line\":21,\"ch\":14},{\"line\":21,\"ch\":25}],[{\"line\":22,\"ch\":0},{\"line\":22,\"ch\":2}],[{\"line\":22,\"ch\":14},{\"line\":22,\"ch\":21}]]"}
!@%STYLE%@!

Use the complete minimum example to follow inline implementations and dispatch based on the combined types of two arguments. section 16.6

How Modern C covers it

How deep it goes
Explains _Generic syntax, function-pointer dispatch, arithmetic promotions, and two-argument selection, but defers exhaustive macro coverage.
Examples
Uses fabs dispatch, a floating-point minimum macro, maximum-value macros, and type-generic tracing conversions.
What it assumes
Assumes basic C expressions and functions while teaching _Generic dispatch, arithmetic promotions, and type-specific macro design.
What you can do after
Builds type-generic C interfaces by combining _Generic selections with macros and type-specific functions.
How it connects
Links macros with _Generic, function pointers, inline functions, arithmetic conversions, and mathematical library functions.

Also explained in

Compare how 2 books explain type-generic macro →

Related concepts

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