我正在寻找这样的片段。我希望它知道在编译时是否在处理数组,并避免以下错误。
#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。例如,让宏创建所有初始化程序的复合文字,然后将其初始化。
#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
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句