我正在尝试在我的x宏中分配一个值,但我真的不明白为什么它不起作用:
#include <stdio.h>
typedef struct
{
int a;
int b;
} struct_t;
#define MY_LIST \
MY_ELEMENT(a) \
MY_ELEMENT(b)
#define MY_ELEMENT(x) struct_t x; \
x.a=33;
MY_LIST
#undef MY_ELEMENT
int main(void)
{
fprintf(stdout, "a: %d\n", a.a);
return 0;
}
编译时出现以下错误:
test.c:14:2: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘.’ token
x.a=33;
有人可以解释为什么我得到这个错误以及如何解决这个问题吗?
答案 0 :(得分:5)
您需要在源文件slethoprod.c
中检查代码的预处理形式。使用GCC,您可以使用gcc -C -E slethoprod.c > slethoprod.i
来获取它,然后(使用编辑器或寻呼机)检查该slethoprod.i
文件。
它包含以下内容:
struct_t a; a.a = 33; struct_t b; b.a = 33;
这显然不是有效的C代码(因为它在任何功能之外在文件scope中都有某些赋值;请记住,initialization中的declaration不是不是< / em>一个assignment)。
您可能希望具有一些定义(带有初始化),例如
struct_t a = {33};
,甚至(出于可读性考虑)struct initialization之类的
struct_t b = {.a=33};
您可以通过花哨的preprocessor技巧来达到目的。
浏览一些C reference网站和/或学习C11标准n1570,以了解有关C的更多信息。另请阅读编译器(例如GCC)和预处理器的文档(例如cpp)。
顺便说一句,我个人认为将一个全局名称与其中的某个字段命名为a
的味道不好(即使它是合法的,因为字段名称和全局变量具有不同的namespaces) 。出于可读性考虑,我建议避免这种情况。
答案 1 :(得分:3)
在函数范围之外为结构字段分配值是不合适的,因此您的原始代码不起作用
#define MY_ELEMENT(x) struct_t x; \
x.a=33;
MY_LIST //<-- Inaproppriate
#undef MY_ELEMENT
如果要使用当前宏,则应这样写:
#include <stdio.h>
typedef struct
{
int a;
int b;
} struct_t;
#define MY_LIST \
MY_ELEMENT(a) \
MY_ELEMENT(b)
#define MY_ELEMENT(x) struct_t x; \
x.a=33;
int main(void)
{
MY_LIST;
fprintf(stdout, "a: %d\n", a.a);
return 0;
}
或者您可以通过以下方式更改宏:#define MY_ELEMENT(x) struct_t x = {33, 0};
甚至更好的是:#define MY_ELEMENT(x) struct_t x = {.a = 33};
,并保留其余代码。
这样,您将在宏中初始化变量。
答案 2 :(得分:-2)
您指的错误主要是在代码中某处缺少;
时发生的。
在这种情况下,如果您在\
之后添加x.a=33;
,然后调用MY_LIST
,则会消失。
但是随后您应该在函数MY_LIST
中调用a
,以在main
中定义
这是您的代码的有效版本
#include <stdio.h>
typedef struct
{
int a;
int b;
} struct_t;
#define MY_LIST \
MY_ELEMENT(a) \
MY_ELEMENT(b)
#define MY_ELEMENT(x) struct_t x; \
x.a=33;
int main(void)
{
MY_LIST;
fprintf(stdout, "a: %d\n", a.a);
return 0;
}