问题描述
我正在寻找这样的片段.我希望它知道在编译时是否正在处理数组,并避免出现以下错误.
I'm looking for something like this snippet.I expect it to know, at compile time, wether it is dealing with an array or not, and avoid the following errors.
#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'是一个数组,编译器也是如此.
When I do write GENERIC_ASSIGN(bar,int) i do know that 'bar' is an ARRAY, so does the compiler.
请参阅此主题,以解释问题的一部分
See this topic that explains one part of the problem here
如果在宏中允许使用"#if",该问题将很容易解决
The problem would have been solved easily if '#if' were allowed inside macros
推荐答案
您无法分配给数组,因此必须使用memcpy.例如,让宏创建所有初始化程序的复合文字,然后将其初始化.
You can't assign to arrays, so you will have to use memcpy. For example, have the macro create a compound literal of all initializers and then memcpy that one.
#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;
}
值得注意的是,使用此方法实际上与使用什么类型(是否使用数组)无关紧要.初始化列表的大小很重要.
Notably, with this method it doesn't really matter what type you use, array or not. The size of the initializer list is all that matters.
gcc -O2将其解析为几个寄存器加载(x86):
gcc -O2 resolves this into a couple of register loads (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
这篇关于在不知道函数代码中其性质的情况下分配数组或整数(但编译器知道)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!