Как присвоить значение внутри моего макроса?

Я пытаюсь присвоить значение внутри моего 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 ответа

Решение

Вы должны посмотреть на предварительно обработанную форму вашего кода в исходном файле 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 поскольку некоторые поля в нем имеют плохой вкус (даже если это допустимо, поскольку имена полей и глобальные переменные имеют разные пространства имен). Для удобства чтения я рекомендую избегать этого.

Присвоение значений структурным полям вне области действия функции не подходит, поэтому ваш исходный код не работает

#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.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;
}
Другие вопросы по тегам