在函数代码中不知道其性质的情况下分配数组或整数(但编译器知道)
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
我正在寻找与此片段类似的内容。 我希望它在编译时知道它是否正在处理数组,并避免以下错误。
#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