C-如何在宏中分配值?

时间:2019-01-12 08:09:58

标签: c x-macros

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

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

3 个答案:

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