首页 > 解决方案 > 如果这是一个数组还是一个整数,有没有办法在编译时知道(并且不会失败)?

问题描述

操作:

有没有办法在编译时知道当前对象是数组还是整数?

#include <stdio.h>

#define IS_INDEXABLE(arg) (sizeof(arg[0]))
#define IS_ARRAY(arg) (IS_INDEXABLE(arg) && (((void *) &arg) == ((void *) arg)))

int main(void)
{
    int a[5]; // array
    int *b = a; // pointer
    int n = 10;
    int c[n]; // VLA
    int d = 4; // integer

    printf("%d\n", IS_ARRAY(a)); //works, 1
    printf("%d\n", IS_ARRAY(b)); //works, 0 (edit: I want it to be 1)
    printf("%d\n", IS_ARRAY(c)); //works, 1 
    printf("%d\n", IS_ARRAY(d)); //should say 0, but does not compile "error: subscripted value is neither array nor pointer nor vector"
    return 0;
}


编辑答案:

经过反思,我最终得到以下观察结果:

对于问题的第一部分,大多数答案都是正确的,而且我的提议也有效。

#define IS_ARRAY1(arg) (((void *) &arg) == ((void *) arg))
#define IS_ARRAY2(arg,type) ((sizeof(arg)/sizeof(type) != 1) && (sizeof(arg)/sizeof(type) != sizeof(arg)))
#define IS_ARRAY4(x,type) _Generic((&x), \
                          type (*)[]: 1, \
                          default:   0)

问题的第二部分将在这里处理 谢谢。

标签: carraysmacroscompile-time

解决方案


由于_Generic基于应比较表达式与“关联列表”中所有内容的类型兼容性的要求,您可以这样做:

#define IS_INT_ARRAY(x) _Generic((&x),          \
                                 int (*)[]: 1,  \
                                 default:   0)

如果参数是int数组,那么它将与指向int不完整类型(未知大小)数组的数组指针兼容。

如果参数是对象指针,您可以申请&,但不会产生数组指针。


推荐阅读