FUNC(param);
当param
为char *
时,请发送至func_string
。
当它为int
时,发送到func_int
我认为可能有一个解决方案,因为变量类型在编译时是已知的。
答案 0 :(得分:12)
这可以使用C1X,但不能用现行标准。
看起来像这样:
#define cbrt(X) _Generic((X), long double: cbrtl, \
default: cbrt, \
float: cbrtf)(X)
答案 1 :(得分:11)
变量类型是编译器已知的,但不是预处理器(它将代码简单地视为非结构化文本一个标记流,并且只对其执行简单的替换操作)。所以我担心你无法通过C宏实现这一点。
在C ++中,他们发明了模板来解决这些问题(等等)。
答案 2 :(得分:5)
您可以测试类型的特征。
例如,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's statement expression,它允许一组语句为右值。
__builtin_choose_expr()
内置函数可以选择要编译的表达式。使用__builtin_types_compatible_p,如果param的类型与int
和char*
不兼容,则允许在编译时触发错误:(在这种情况下编译somehting无效)
#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) \
) \
)
这实际上是__builtin_choose_expr docs的一个稍微修改过的例子。
答案 3 :(得分:4)
在C89 / ANSI C中不可能运行时间检查类型,但是gcc有一个扩展允许它。如果我记得,那些类型或类似的东西。我曾经在Linux内核中看到过它。
在kernel.h中:
#define min(x, y) ({ \
typeof(x) _min1 = (x); \
typeof(y) _min2 = (y); \
(void) (&_min1 == &_min2); \
_min1 < _min2 ? _min1 : _min2; })
看一下这篇文章:GCC hacks in the Linux kernel
当我第一次看到这个时,我实际上就此问了一个问题:
我不太清楚你将如何使用它来解决你的问题,但这是值得一看的事情。
答案 4 :(得分:1)
使用宏无法执行此操作。宏的值在编译时被替换,并且没有被解释。他们只是换人。
答案 5 :(得分:1)
变量类型在编译时确实已知,但是在编译之前会进行宏扩展。我建议你实现2个重载函数而不是宏。