这开始是一个玩笑类型的Cython,我做了很多愚蠢的定义来使用C模拟python。然后我意识到它实际上很方便调试和快速黑客程序。
我有一个主要工作的定义,使用sizeof
来区分类型,但是3或7个字符的char数组/字符串+ \0
将被打印为double或int。有没有办法解决?我正在考虑使用try-exception来下标它以查看它是否是一个字符串,但我无法实现它。
#include <stdio.h>
#define print(n) if(sizeof(n)==8) printf("%f\n",n); \
else if(sizeof(n)==4) printf("%i\n",n); \
else printf("%s\n",n);
int main()
{
print("Hello world!") // these all work perfectly
print(8.93)
print(4)
print("abc") // these are interpreted as ints or doubles
print("1234567")
return 0;
}
答案 0 :(得分:3)
gcc有一个方便的内置(也可用于clang),可以直接比较类型:
int __builtin_types_compatible_p(type1,type2)
如果类型为type1和type2的非限定版本,则此内置函数返回1 (它们是类型,而不是表达式)是兼容的,否则为0。这种内置的结果 function可以在整数常量表达式中使用。
http://gcc.gnu.org/onlinedocs/gcc/Other-Builtins.html
这个内置函数用于linux内核中特定于类型的调度和类型检查,仅举一例。
要从表达式中获取类型,您可以依赖typeof()
语句来调整:
__builtin_types_compatible_p (typeof(n), int)
答案 1 :(得分:3)
可以使用_Generic
构造选择基于参数类型的操作:
#define print(X) _Generic((0, X), int: print_int, \
double: print_double, \
char *: print_string)(X)
void print_int(int x) { printf("%d\n", x); }
// etc
所有_Generic
做的是选择其列表中的一个表达式 - 这就是宏的参数出现两次的原因(一次根据其类型选择,一次实际应用它)选择哪个功能/值)。您还可以提供默认表达式。 Apparently逗号表达式((0, X)
)是轻松支持字符串文字所必需的:它将字符串衰减为char *
。
_Generic
可用于支持C11的编译器(包括GCC和Clang)。 Jens Gustedt's P99中的某些C99编译器也有解决方法。
答案 2 :(得分:3)
Modern C,AKA C11,类型通用宏有_Generic
。像
#define P(x) printf(_Generic(x, unsigned: "%u", signed: "%d", double: "%g"), x)
应该这样做。
答案 3 :(得分:0)
非C ++ 11版本或许只是重载一个函数......它显然不仅仅是一个宏:
void print_var(const char *s)
{
printf("%s", s);
}
void print_var(unsigned int u)
{
printf("%u", u);
}
void print_var(int d)
{
printf("%d", d);
}
void print_var(double f)
{
printf("%f", f);
}
#define print(v) { print_var(v); \
printf("\n"); }
int main()
{
print("abc")
print(1234)
print(-13)
print(3.141592654)
print("1234567")
print("Hello world!")
print(8.93)
print(4)
if(1)
print("this too")
if(2)
print("and this")
}
产生输出:
abc
1234
-13
3.141593
1234567
Hello world!
8.930000
4
this too
and this