Вы можете проверить характеристики типов.
Например, int
может содержать отрицательное значение, а char*
- нет.Так что если ((typeof(param))-1) < 0
, param
не подписано:
if (((typeof(param))-1) < 0) {
do_something_with_int();
} else {
do_something_with_char_p();
}
Компилятор, очевидно, оптимизирует это.
Попробуйте это здесь: http://ideone.com/et0v1
Это было быдаже проще, если типы были разных размеров.Например, если вы хотите написать универсальный макрос, который может обрабатывать символы разных размеров:
if (sizeof(param) == sizeof(char)) {
/* ... */
} else if (sizeof(param) == sizeof(char16_t)) {
/* ... */
} else if (sizeof(param) == sizeof(char32_t)) {
/* ... */
} else {
assert("incompatible type" && 0);
}
GCC имеет встроенную функцию __builtin_types_compatible_p()
, которая может проверять совместимость типов:
if (__builtin_types_compatible_p(typeof(param), int)) {
func_int(param);
} else if (__builtin_types_compatible_p(typeof(param), char*)) {
func_string(param);
}
Попробуйте здесь: http://ideone.com/lEmYE
Вы можете поместить это в макрос, чтобы достичь того, что вы пытаетесь сделать:
#define FUNC(param) ({ \
if (__builtin_types_compatible_p(typeof(param), int)) { \
func_int(param); \
} else if (__builtin_types_compatible_p(typeof(param), char*)) { \
func_string(param); \
} \
})
(({...})
является выражением оператора GCC , оно позволяет группе операторов быть значением.
Встроенное __builtin_choose_expr()
может выбрать выражение для компиляции.С __builtin_types_compatible_p это позволяет вызвать ошибку во время компиляции, если тип параметра несовместим как с int
, так и с char*
: (компилируя что-то недопустимое в этом случае)
#define FUNC(param) \
__builtin_choose_expr(__builtin_types_compatible_p(typeof(param), int) \
, func_int(param) \
, __builtin_choose_expr(__builtin_types_compatible_p(typeof(param), char*) \
, func_string(param) \
, /* The void expression results in a compile-time error \
when assigning the result to something. */ \
((void)0) \
) \
)
Этофактически слегка измененный пример из __buildin_choose_expr docs .