Как спроектировать мой макрос, чтобы он содержал возвращаемое значение функции - PullRequest
0 голосов
/ 16 сентября 2018

Чтобы не задавать проблему XY, сначала я хотел бы описать свое намерение.Существует много самоопределенных структур, все они являются статическими одноэлементными переменными .Я хотел бы разработать макрос (или функцию), чтобы получить конкретный адрес к тому, что я хочу.Вот что я делаю до сих пор:

/* the struct of apple, banana and cherry have been defined somewhere above
 * BUT NOT YET DECLARED */

const char *fruit_name[3] = {
    "apple",
    "banana",
    "cherry"
};

Я ожидал, что пользователь сможет получить указатель на структуру просто, предложив число, то есть 0, чтобы получить ptr для структуры apple, 1, чтобы получитьptr для структуры банана и т. д.

И я объявляю статическую переменную следующим образом:

#define DEFSTRUCT(struct_name) \
    static struct struct_name my##struct_name(void)  \
    { \
        static struct strcut_name singleton;  \
        return &singleton; \
    }

Затем я использую ее для генерации 3 функций, которые будут возвращать указатель на структуры:

DEFSTRUCT(apple)    // whenever calls myapple() I got the reference to static struct apple 
DEFSTRUCT(banana)
DEFSTRUCT(cherry)

Вот самая неприятная часть: я НЕ МОГУ сделать макрос (или функцию) для передачи строки, чтобы получить к ним доступ

Вот что я сделал, но напрасно:

#define GETSTRUCT(struct_name) my##struct_name()

void get_fruit(void *ptr, int num) {
    ptr = GETSTRUCT(fruit_name[num]);  // I expect that ptr would points to static struct apple if num is 0;
}

Как бы я ни старался, fruit_name [num] НЕ БУДЕТ перенесено в правильное имя строки. Кто-нибудь может указать, какую ошибку я допустил?Огромное спасибо

1 Ответ

0 голосов
/ 16 сентября 2018

Невозможно расширить параметр функции num до его значения в раскрытии макроса или развернуть элемент массива strings до его строки в раскрытии макроса.Оба из них требуют оценки, которая никогда не происходит в препроцессоре.

Функция для возврата указателя на структуру может быть:

struct struct_name *get_fruit(void *pointer, int index)
{
    static struct struct_name ArrayOfTheseThings[] =
    {
        { contents of "apple" struct },
        { contents of "banana" struct },
        { contents of "cherry" struct },
    };

    return &ArrayOfTheseThings[index];
}

или:

struct struct_name *get_fruit(void *pointer, int index)
{
    const static struct struct_name *ArrayOfPointers[] =
    {
        &NameOfAppleStructDefinedElsewhere;
        &NameOfBananaStructDefinedElsewhere;
        &NameOfCherryStructDefinedElsewhere;
    };

    return ArrayOfPointers[index];
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...