Skip to content

Commit 651e46a

Browse files
committed
add note about _Generic
1 parent 95297e1 commit 651e46a

1 file changed

Lines changed: 52 additions & 0 deletions

File tree

docs/api.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,58 @@ Some examples of typical name changes:
4545

4646

4747

48+
### The _Generic selection
49+
50+
The C11 standard introduced the
51+
[`_Generic`](http://en.cppreference.com/w/c/language/generic)
52+
selection function. This function allows for automatic selection of
53+
different function variants at compile time depending on the type of the
54+
function arguments mimicing polymorph C++ functions.
55+
56+
Recent versions of SDCC already support this function (command line argument
57+
`--std-sdcc99`), but it's usefulness is still limited to some special cases.
58+
59+
```c
60+
#define Serial_print(X) _Generic((X), \
61+
char*: Serial_print_s, \
62+
signed long: Serial_print_i, \
63+
signed int: Serial_print_i, \
64+
signed char: Serial_print_c, \
65+
unsigned long: Serial_print_u, \
66+
unsigned int: Serial_print_u, \
67+
unsigned char: Serial_print_u \
68+
)(X)
69+
```
70+
71+
This would unify some, but not all print function variants:
72+
73+
|C++ name | C name using _Generic |
74+
|-------- | ------------------ |
75+
|`Serial.print(int)` | `Serial_print` |
76+
|`Serial.print(unsigned)` | `Serial_print` |
77+
|`Serial.print(char)` | `Serial_print` |
78+
|`Serial.print(char *)` | `Serial_print_s` |
79+
|`Serial.print(char *buf, int len)` | `Serial_print_n` |
80+
|`Serial.print(unsigned n, int base)` | `Serial_print_ub` |
81+
82+
Unfortunately cpp does not match string constants and `char*` resulting in a
83+
very non-regular usage pattern:
84+
85+
char *string="Hello";
86+
87+
Serial_print(string); // works
88+
Serial_print("Hello"); // doesn't work
89+
Serial_print_s("Hello");// works
90+
91+
To avoid too much confusion it might be better to not use `_Generic` at all.
92+
93+
Another problem using the `_Generic` selector is configurable instance
94+
names. The preprocessor does not allow for variable macro names. That means
95+
`_Generic` would work with fixed name like `Serial`, but it wouldn't work
96+
for `SoftwareSerial` with no standard instance name.
97+
98+
99+
48100
49101
## Inheritance from Print class
50102

0 commit comments

Comments
 (0)