Вернуть typedef в C - PullRequest
       32

Вернуть typedef в C

1 голос
/ 28 сентября 2011

В файле .h я определил:

#define PAIR_TYPE(type1, type2)\
    typedef struct {     \     // added \ after edit  
      type1 first;       \     // added \ after edit  
      type2 second;      \     // added \ after edit  
    };     // added ; after edit        
#define MAKE_PAIR(val1, val2) {val1, val2}
PAIR_TYPE(char *, uint32_t) mypair;
mypair foo();

В файле .c я использовал его так:

mypair foo()
{
   mypair p;
   uint32_t bar = calculate();
   p = MAKE_PAIR("normal", target);
   return p;
}

Однако я получаю эту ошибку:

ошибка: ожидаемое выражение перед токеном ‘{’

Линия, на которую он указывает:

p = MAKE_PAIR("normal", target);

Я не знаю, почему там написано '{' !!! в этой строке нет '{'.

Ответы [ 4 ]

7 голосов
/ 28 сентября 2011

Вам нужно больше обратной косой черты в строках после '{'

#define PAIR_TYPE(type1, type2)\
  typedef struct {\
    type1 first;\
    type2 second;\
  }
3 голосов
/ 28 сентября 2011

Да, есть!Но это скрыто от ваших глаз магией препроцессора.Помните, препроцессор - это зло , и вы, безусловно, злоупотребляете им.

Препроцессор просто выполняет текстовую подстановку, поэтому код, который видит компилятор, на самом деле:

p = {"normal", target};

И это неверный синтаксис Си.Там, видите, '{'.Этот синтаксис действителен только при инициализации, а не в присваиваниях:

mypair a = {"a", 1}; /* ok */
a = {"a", 1}; /* error */
0 голосов
/ 28 сентября 2011

Может быть, если вы используете cdiom для написания макроса, как показано в ссылке, у вас не будет проблем, с которыми вы сталкиваетесь. Подробнее см. http://c -faq.com / cpp / multistmt.html .

0 голосов
/ 28 сентября 2011

В вашем макросе PAIR_TYPE вам нужно избавиться от точки с запятой в конце, чтобы имя, которое вы даете для типа, было частью typedef.Прямо сейчас, когда вы делаете:

PAIR_TYPE(char *, uint32_t) mypair;

.. вы получаете:

typedef struct {
  char * first;
  uint32_t second;
}; mypair;

.. с точкой с запятой между } и mypair, которая не должна бытьтам.

Вам также понадобится использовать приведение для вашего макроса MAKE_PAIR, чтобы работать так, как вы его используете.Прямо сейчас строка:

p = MAKE_PAIR("normal", target);

.. расширяется до:

p = {"normal", target};

.., которая не будет работать.Но если вы добавите приведение:

p = (mypair)MAKE_PAIR("normal", target);

.., тогда расширенная строка будет:

p = (mypair){"normal", target};

.., которая может работать, так как приведение типа сообщает компилятору, какие поля между{ и } должны быть.Обратите внимание, что вы устанавливаете char * в первом поле, чтобы указывать на литерал "normal", а не копировать строку.

...