Выход из поля структуры в определении макроса - PullRequest
0 голосов
/ 07 января 2019

У меня есть следующая структура (упрощенно):

struct error_t{
    const char *file;
    const char *error_desc;
};

Я написал макрос для создания структуры

#define ERROR_SET(error_desc) \
{ \
   struct error_t tmp = {.error_desc = error_desc, .file = __FILE__}; \
   struct error_t *ptr = malloc(sizeof(*ptr)); \
   memcpy(ptr, &tmp, sizeof(tmp)); \
   *error_ptr = ptr; \
}

Проблема в том, что на линии

struct error_t tmp = {.error_desc = error_desc, .file = __FILE__}

оба error_desc s .error_desc = error_desc заменены, что не то, что я хотел. Единственное решение, которое я вижу, - переименовать параметр макрофункции с error_desc на _error_desc, но, возможно, есть лучший способ. Может быть, мы можем «убежать» от error_desc для замены в .error_desc?

Ответы [ 3 ]

0 голосов
/ 07 января 2019

У вас может быть другой MACRO, который препроцессор заменит на error_desc.

#define ERROR_DESC error_desc

Тогда вы можете определить ERROR_SET следующим образом:

#define ERROR_SET(error_desc) \
{ \
   struct error_t tmp = {.ERROR_DESC = error_desc, .file = __FILE__}; \
   struct error_t *ptr = malloc(sizeof(*ptr)); \
   memcpy(ptr, &tmp, sizeof(tmp)); \
   *error_ptr = ptr; \
}

Это работает, потому что замена выполняется только один раз.

0 голосов
/ 07 января 2019

Только не используйте одно и то же имя для параметра и члена структуры

0 голосов
/ 07 января 2019

Вы можете «обмануть» препроцессор чем-то вроде

#define CONCAT(a, b) a##b

#define ERROR_SET(error_desc) \
{ \
   struct error_t tmp = { .CONCAT(error,_desc) = error_desc, .file = __FILE__ }; \
   ...\
}

но оно того не стоит. Просто переименуйте параметр. И разработайте соглашение для именования параметров, которое поможет вам избежать таких конфликтов имен в будущем.


Если подумать, дополнительный макрос CONCAT даже не нужен. Это достигнет той же цели

#define ERROR_SET(error_desc) \
{ \
   struct error_t tmp = { .error##_desc = error_desc, .file = __FILE__ }; \
   ...\
}
...