1

我试图在我的 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;

有人可以解释为什么我会收到这个错误以及如何解决这个问题吗?

4

3 回答 3

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 代码(因为它在文件范围内的任何函数之外都有一些赋值;请记住,声明中的初始化不是赋值)。

您可能想要一些定义(带有初始化),例如

struct_t a = {33};

甚至(出于可读性目的)结构初始化,如

struct_t b = {.a=33};

你可以玩花哨的预处理器技巧来获得它。

查看一些C 参考站点和/或研究 C11 标准n1570以了解有关 C 的更多信息。还请阅读编译器(例如GCC)和预处理器(例如cpp)的文档。

顺便说一句,我个人觉得将全局命名为与其中的某些字段同名a是很糟糕的(即使它是合法的,因为字段名称和全局变量具有不同的命名空间)。出于可读性目的,我建议避免这样做。

于 2019-01-12T08:14:51.390 回答
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};

并保持其余代码不变。

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

于 2019-01-12T08:24:27.573 回答
-2

您所指的错误主要发生;在代码中缺少某处时。
在这种情况下,如果您添加\之后x.a=33;然后调用MY_LIST它就会消失。
但是你应该调用这里定义的MY_LIST函数 是你的代码的工作版本 amain

#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;
}
于 2019-01-12T08:23:05.820 回答