我或多或少地找到了_Generic
这个问题的解决方案。
警告:可能会触发误报(参见下面的示例)。
#define __INTERNAL_CHECK_POINTER(x) _Generic((x),\
int: 0, unsigned int: 0,\
long: 0, unsigned long: 0,\
long long: 0, unsigned long long: 0,\
float: 0, double: 0,\
long double: 0, \
default: 1)
/**
* Determines whether the variable has likely a pointer type (but may be triggered false-positive)
*/
#define IS_LIKELY_A_POINTER(x) ((sizeof(x) == sizeof(void*)) && __INTERNAL_CHECK_POINTER(x) ? 1 : 0)
演示:
char c = 0;
printf("c is a pointer: %s\n", IS_LIKELY_A_POINTER(c) ? "Yes" : "No");
unsigned long long l = 0;
printf("l is a pointer: %s\n", IS_LIKELY_A_POINTER(l) ? "Yes" : "No");
double d = 0.0;
printf("d is a pointer: %s\n", IS_LIKELY_A_POINTER(d) ? "Yes" : "No");
unsigned char* cp = 0;
printf("cp is a pointer: %s\n", IS_LIKELY_A_POINTER(cp) ? "Yes" : "No");
struct tm* tp = 0;
printf("tp is a pointer: %s\n", IS_LIKELY_A_POINTER(tp) ? "Yes" : "No");
char ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
printf("ia is a pointer: %s\n", IS_LIKELY_A_POINTER(ia) ? "Yes" : "No");
这将输出:
c is a pointer: No
l is a pointer: No
d is a pointer: No
cp is a pointer: Yes
tp is a pointer: Yes
ia is a pointer: Yes // false-positive!
如果您(像我一样)正在寻找一些日志记录(*
为特定变量绘制或不绘制 a)并且您不是在寻找防故障结果,试试这个,它可能会有所帮助。干杯!
注意它不会在 MSVC 下编译;使用 gcc/clang/等。代替或使用此条件进行自己的后备实现:
#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)
// use _Generic code
#else
// ¯\_(ツ)_/¯
#endif