以下是我尝试做的最小测试用例;
// minimal test case
#include <stdlib.h>
struct array {
void *ptr;
int numElements;
int capacity;
};
struct task {
char *task_name;
int task_id;
};
#define NEW_ARRAY(TYPE, VARIABLE, CAPACITY) \
struct array VARIABLE; \
VARIABLE.ptr = malloc(CAPACITY * sizeof(TYPE)); \
VARIABLE.capacity = CAPACITY; \
VARIABLE.numElements = 0 \
#define array_for_each(TYPE, ELEM, ARRAY) \
for (int i=0, ELEM = *((TYPE *)ARRAY.ptr); \
i<ARRAY.numElements; \
i++, ELEM = *((TYPE *)ARRAY.ptr + i) \
) \
int main() {
NEW_ARRAY(struct task, my_tasks, 2);
struct task tmp;
array_for_each(struct task, tmp, my_tasks) {
;
}
return 0;
}
我到了;
test.c:22:23:hata:初始化类型&#39; int&#39;时不兼容的类型 使用类型结构任务&#39; for(int i = 0,ELEM = *((TYPE *)ARRAY.ptr); \
扩展后的那条宏观线,转向:
for (int i=0, tmp = *((struct task *)my_tasks.ptr); i<my_tasks.numElements; i++, tmp = *((struct task *)my_tasks.ptr + i) ) {
;
}
好的,所以tmp是struct task
,我正在将my_tasks.ptr投射到void *
到struct task *
并取消引用它,所以我应该给我一个struct task
。所以我不知道为什么gcc会给我这个错误。
答案 0 :(得分:2)
如果您有以下代码:
for (int i=0, tmp = *((struct task *)my_tasks.ptr); ...
tmp
是for
循环范围内的新变量,其类型为int
。
答案 1 :(得分:1)
在如下声明中:
int i = 0, tmp = ....;
声明int
名为i
和tmp
。但是您尝试使用tmp
初始化此新struct task
。
我猜你试图将声明int i = 0;
与引用现有变量tmp = ....
的声明tmp
结合起来,但这是不可能的。要解决此问题,您可以将ELEM=
部分提升到for(
之前。
BTW考虑使用指针使循环工作而不是按值复制每个元素,然后可以修改数组中的值。这种方法的一个好处是你甚至不需要i
。 (您可以使用指针减法来知道何时到达循环的末尾),这样您就不会遇到原始问题。
答案 2 :(得分:0)
for循环有两种不同的有效语法。它可以是:
for (expr_opt1 ; expr_opt2 ; expr_opt3)
或
for (declartion expr_opt1 ; expr_opt2)
你试图通过在循环范围中声明一个新变量i并试图初始化tmp来混合这两个变量。编译器认为您尝试使用循环范围声明 TWO 新变量i和tmp,类型为int,然后使用struct任务初始化tmp。后一点是为什么会有错误。