Хотелось бы знать причину предупреждений, это стандартное поведение или несовершенство препроцессора?
Препроцессор-то тут ни при чём. Если посмотреть в
препроцессированный код,
_Generic((1), int : _Generic((2), int : fnk(1, 2,
# 37 "generic.c" 3 4
((void *)0)
# 37 "generic.c"
), char * : fnk(1, 0, 2)));
printf("\n2.2)---------\n");
_Generic((1), int : _Generic(("2"), int : fnk(1, "2",
# 40 "generic.c" 3 4
((void *)0)
# 40 "generic.c"
), char * : fnk(1, 0, "2")));
то видно, что выражение выбираемое _Generic имеет правильные типы, но выражения в других ветках при этом имеют неправильные типы. Предупреждение об этом.
Пофиксить можно было бы заведя две разные функции для int и char * и выбирая в _Generic только нужную функцию, а не всё выражение. Типа того:
void fnk_int(uintmax_t A, uintmax_t B){
...
}
void fnk_pchar(uintmax_t A, char *B){
...
}
#define FFF_B(A, BC) \
_Generic((A), \
int : _Generic((BC), \
int : fnk_int, \
char * : fnk_pchar)(A, BC))