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};

其余代码保持原样。

这样您就可以在宏中初始化您的变量。