有没有办法在编译时知道(而不是失败)这是一个数组还是一个整数?

is there a way to know (and not fail) at compile time if this is a array or an integer?

OP:

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

#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)

第二部分问题会处理 谢谢。

Linux 内核 (gcc, clang) 有

/* Are two types/vars the same type (ignoring qualifiers)? */
#define __same_type(a, b) __builtin_types_compatible_p(typeof(a), typeof(b))

/* &a[0] degrades to a pointer: a different type from an array */
#define __must_be_array(a)  BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))

因为 _Generic 是基于表达式应该与 "association list" 中的所有内容进行类型兼容性比较的要求,你可以这样做:

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

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

如果参数是一个对象指针,您可以应用&但它不会产生数组指针。