在函数代码中不知道其性质的情况下分配数组或整数(但编译器知道)

Assign an array or an integer without knowing its nature in the function code (but compiler knows)

我正在寻找与此片段类似的内容。 我希望它在编译时知道它是否正在处理数组,并避免以下错误。

#include <stdio.h>


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

#define GENERIC_ASSIGN(arg,type) if(IS_ARRAY(arg,type)){arg[0] = 1; arg[1] = 2;}else{arg = 2;}

int main(void)
{

    int foo = 0;
    int bar[10] = {0};

    GENERIC_ASSIGN(bar,int); //-->  error: assignment to expression with array type
    GENERIC_ASSIGN(foo,int); //--> error: subscripted value is neither array nor pointer nor vector  "arg[0] = 1; arg[1] = 2;"

    return 0;
}

当我写 GENERIC_ASSIGN(bar,int) 时,我知道 'bar' 是一个数组,编译器也是。

请参阅本主题,该主题解释了问题的一部分

如果在宏中允许“#if”,问题就很容易解决了

你不能给数组赋值,所以你必须使用 memcpy。例如,让宏创建所有初始值设定项的复合文字,然后 memcpy 那个。

#include <stdio.h>
#include <string.h>

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

#define INIT(arg, type, ...) memcpy(&(arg),                         \
                                    (type[]){__VA_ARGS__},          \
                                    sizeof((type[]){__VA_ARGS__})) 

#define GENERIC_ASSIGN(arg,type) IS_ARRAY(arg,type) ?               \
                                 INIT(arg,type,1,2) :               \
                                 INIT(arg,type,2)

int main(void)
{
  int foo = 0;
  int bar[10] = {0};

  GENERIC_ASSIGN(bar,int);
  GENERIC_ASSIGN(foo,int);

  printf("%d %d\n",bar[0], bar[1]);
  printf("%d\n",foo);

  return 0;
}

值得注意的是,使用这种方法,使用什么类型(数组与否)并不重要。初始化列表的大小是最重要的。

gcc -O2 将其解析为几个寄存器加载 (x86):

    mov     edx, 2
    mov     esi, 1
    xor     eax, eax
    mov     edi, OFFSET FLAT:.LC0
    call    printf
    mov     esi, 2
    mov     edi, OFFSET FLAT:.LC1
    xor     eax, eax
    call    printf