Перегрузка функции через макрос, предупреждение в _Generic на каст перекрестно

Есть код, в котором происходит перегрузка функции через макрос.

Компилятор выдаёт предупреждение на каст переменных, но скомпилированная программа работает правильно. Подавление предупреждений не вариант.

Хотелось бы знать причину предупреждений, это стандартное поведение или несовершенство препроцессора?

Минимальный код для проверки и экспериментов.

#include <inttypes.h>
#include <stdint.h>
#include <stdio.h>
 
#define FNK(...) \
        FFF_x(, \
                ##__VA_ARGS__, \
                FFF_B(__VA_ARGS__), \
                FFF_A(__VA_ARGS__), \
                FFF_0(__VA_ARGS__))
 
#define FFF_x(x, A, B, FFF, ...)FFF
 
#define FFF_0() fnk(0, 0, NULL)
#define FFF_A(A) fnk(A, 0, NULL)
 
#define FFF_B(A, BC) \
        _Generic((A), \
                int : _Generic((BC), \
                        int : fnk(A, BC, NULL), \
                        char * : fnk(A, 0, BC)))
 
void fnk(uintmax_t A, uintmax_t B, char* C){
    printf("A : %"PRIXMAX"\n", A);
    printf("B : %"PRIXMAX"\n", B);
    printf("C : \"%s\"\n", C);
}
 
void fnk_test(void){
    printf("\n0)---------\n");
    FNK();
 
    printf("\n1)---------\n");
    FNK(1);
 
    printf("\n2.1)---------\n");
    FNK(1, 2);
 
    printf("\n2.2)---------\n");
    FNK(1, "2");
}
 
int main() {
    fnk_test();
    return 0;
}

В FNK(1, 2); -- ругается на то, что переменная не char * ,а в FNK(1, "2"); -- наоборот, что не int.

Вывод программы:

0)---------
A : 0
B : 0
C : "(null)"
 
1)---------
A : 1
B : 0
C : "(null)"
 
2.1)---------
A : 1
B : 2
C : "(null)"
 
2.2)---------
A : 1
B : 0
C : "2"

Предупреждения: введите сюда описание изображения


Ответы (1 шт):

Автор решения: RR-Zz

Решение:

#define INT_OR_0(A) _Generic((A), int: (A), default: 0)
#define CHARP_OR_NULL(A) _Generic((A), char *:(A), default: NULL)

#define FFF_B(A, BC) \
        _Generic((A), \
                int : _Generic((BC), \
                        int : fnk(A, INT_OR_0(BC), NULL), \
                        char * : fnk(A, 0, CHARP_OR_NULL(BC))))

Подробнее тут: https://qna.habr.com/q/816309

→ Ссылка