C - 如何在我的宏中赋值?
C - How to assign a value inside my macro?
我正在尝试在我的 x-macro 中分配一个值,但我真的不明白为什么它不起作用:
#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;
有人可以解释为什么我会收到这个错误以及如何解决这个问题吗?
您需要查看源文件中代码的预处理形式 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; remember that an initialization in a declaration is not an assignment 中的任何函数之外都有一些赋值)。
您可能想要一些定义(带有初始化),例如
struct_t a = {33};
甚至(出于可读性目的)一个 struct initialization 喜欢
struct_t b = {.a=33};
你可以玩花哨的 preprocessor 技巧来获得它。
研究一些 C reference site and/or study the C11 standard n1570 to learn more about C. Read also the documentation of your compiler (e.g. GCC) and of your preprocessor (e.g. cpp)。
顺便说一句,我个人觉得将全局变量命名为a
与其中的某个字段同名是很糟糕的(即使它是合法的,因为字段名称和全局变量具有不同的namespaces).出于可读性目的,我建议避免这种情况。
您提到的错误主要发生在代码某处缺少 ;
时。
在这种情况下,如果您在 x.a=33;
之后添加 \
然后调用 MY_LIST
它就会消失。
但是你应该在main
中定义a
的函数中调用MY_LIST
这是您的代码的工作版本
#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; \
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};
其余代码保持原样。
这样您就可以在宏中初始化您的变量。
我正在尝试在我的 x-macro 中分配一个值,但我真的不明白为什么它不起作用:
#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;
有人可以解释为什么我会收到这个错误以及如何解决这个问题吗?
您需要查看源文件中代码的预处理形式 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; remember that an initialization in a declaration is not an assignment 中的任何函数之外都有一些赋值)。
您可能想要一些定义(带有初始化),例如
struct_t a = {33};
甚至(出于可读性目的)一个 struct initialization 喜欢
struct_t b = {.a=33};
你可以玩花哨的 preprocessor 技巧来获得它。
研究一些 C reference site and/or study the C11 standard n1570 to learn more about C. Read also the documentation of your compiler (e.g. GCC) and of your preprocessor (e.g. cpp)。
顺便说一句,我个人觉得将全局变量命名为a
与其中的某个字段同名是很糟糕的(即使它是合法的,因为字段名称和全局变量具有不同的namespaces).出于可读性目的,我建议避免这种情况。
您提到的错误主要发生在代码某处缺少 ;
时。
在这种情况下,如果您在 x.a=33;
之后添加 \
然后调用 MY_LIST
它就会消失。
但是你应该在main
中定义a
的函数中调用MY_LIST
这是您的代码的工作版本
#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; \
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};
其余代码保持原样。
这样您就可以在宏中初始化您的变量。