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

