So one side effect of C being a mess is that bool and char constants are formatted as integers by default. You have to either cast them to the correct type or use an explicit format specifier which is a bit annoying.
@vitaut do you mean true/false constants?
They are _Bool type in C23
Char constants still int .
@thradams @vitaut _Bool goes all the way back to C99, C23 actually deprecated it in favour of 'bool' (eg. stdbool.h no longer needed), both are "proper" bools, but AFAIK the C standard doesn't enforce a specific size
@thradams @vitaut also I suspect that the problem might be that _Bool/bool implicitly converts to int (eg I guess in vararg lists, bools are passed as int, not sure though)
@floooh @thradams I’m not using varargs, the problem is that true/false has int type in C11
@floooh @thradams so it doesn’t work with _Generic
@vitaut @floooh @thradams for back compat, how about your own <fmtbool.h> that re-#defines true and false as (_Bool)1 and (_Bool)0

@joe @vitaut @thradams hmm, clang (and gcc) seem to get it right?

https://www.godbolt.org/z/1xd83zbeW

Compiler Explorer - C

void bla_bool(bool b) { printf("A boolean: %d\n", b); } void bla_int(int i) { printf("An int: %d\n", i); } #define bla(x) _Generic((x), \ bool: bla_bool, \ int: bla_int \ )(x) int main() { bla(true); bla(false); bla(123); return 0; }

@joe @vitaut @thradams ooopsi, wait Clang gets it wrong! One sec...

@joe @vitaut @thradams ah ok, apparently it has been fixed in C23, but C11 gets it wrong:

https://www.godbolt.org/z/1TW3Kndb7

Compiler Explorer - C

void bla_bool(bool b) { printf("A boolean: %d\n", b); } void bla_int(int i) { printf("An int: %d\n", i); } #define bla(x) _Generic((x), \ bool: bla_bool, \ int: bla_int \ )(x) int main() { bla(true); bla(false); bla(123); return 0; }

@floooh @joe @vitaut @thradams true/false are keywords in C only since C23 (macros before)

incidentally, sizeof(true) is 1 in C23, 4 before