База данных макросов C - проверка параметра функции макроса в другом макросе - PullRequest
0 голосов
/ 25 октября 2018

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

Например, определите базу данных в FancyPantsTable.h:

#if defined (MY_FANCY_PANTS_TABLE)
FANCY_PANTS_DB( A, 123)
FANCY_PANTS_DB( B, 456)
FANCY_PANTS_DB( C, 456)
FANCY_PANTS_DB( D, 123)
#endif

Затем в FancyPants.c импортируйте FancyPantsTable.h везде, где вы хотите составить список.

#define numberSought 456

uint8 my456Array [] = {

            #define FANCY_PANTS_DB( aUint8, num ) #if  ( num == numberSought sought ) aUint8, #endif
            #define MY_FANCY_PANTS_TABLE
            #include "FancyPantsTable.h"
            #undef MY_FANCY_PANTS_TABLE
};

#define numberSought 123

uint8 my123Array [] = {

            #define FANCY_PANTS_DB( aUint8, num ) #if  ( num == numberSought sought ) aUint8, #endif
            #define MY_FANCY_PANTS_TABLE
            #include "FancyPantsTable.h"
            #undef MY_FANCY_PANTS_TABLE
};

Шаблоны макросов C трудны для отладки;прямо в #if я получаю сообщение об ошибке «ожидается имя макропараметра».

Возможно ли то, что я делаю.Как я могу это исправить?

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

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

#if defined (MY_FANCY_PANTS_TABLE)

// PREAMBLE
#ifndef FANCY_PANTS_DB_ENTRY_123
#define FANCY_PANTS_DB_ENTRY_123(...) 
#endif

#ifndef FANCY_PANTS_DB_ENTRY_456
#define FANCY_PANTS_DB_ENTRY_456(...) 
#endif

#define FANCY_PANTS_DB(X, Y) \
        FANCY_PANTS_DB_ENTRY_##Y(X,)

FANCY_PANTS_DB( A, 123)
FANCY_PANTS_DB( B, 456)
FANCY_PANTS_DB( C, 456)
FANCY_PANTS_DB( D, 123)

// EPILOGUE
#undef FANCY_PANTS_DB_ENTRY_123
#undef FANCY_PANTS_DB_ENTRY_456
#undef FANCY_PANTS_DB

#endif

Затем, прежде чем включать файл, вы определяетесоответствующий макрос записи для выдачи своего аргумента.

uint8 my456Array [] = {
            #define FANCY_PANTS_DB_ENTRY_456(...) __VA_ARGS__
            #define MY_FANCY_PANTS_TABLE
            #include "FancyPantsTable.h"
            #undef MY_FANCY_PANTS_TABLE
};

uint8 my123Array [] = {
            #define FANCY_PANTS_DB_ENTRY_123(...) __VA_ARGS__
            #define MY_FANCY_PANTS_TABLE
            #include "FancyPantsTable.h"
            #undef MY_FANCY_PANTS_TABLE
};

Возможно, вы можете скрыть части PREAMBLE и EPILOGUE файла заголовка в отдельные файлы заголовка, которые генерируются из сценария.

0 голосов
/ 25 октября 2018

Помните, макрос не может определить другой .Поэтому строки типа

#define FANCY_PANTS_DB( aUint8, num ) #if  ( num == numberSought sought ) aUint8, #endif

недопустимы.Препроцессор проходит только один раз, поэтому вы не можете использовать что-то вроде этого.

Если я не ошибаюсь, вы можете написать это так, если хотите:

FancyPantsTable.h:

#if MY_FANCY_PANTS_TABLE==123
 A, 
#endif
#if MY_FANCY_PANTS_TABLE==456
 B, 
 C, 
#endif
#if MY_FANCY_PANTS_TABLE==123
 D, 
#endif

FancyPants.c:

#define MY_FANCY_PANTS_TABLE 456

uint8 my456Array [] = {
            #include "FancyPantsTable.h"
             };

#undef MY_FANCY_PANTS_TABLE
#define MY_FANCY_PANTS_TABLE 123

uint8 my123Array [] = {
            #include "FancyPantsTable.h"
            };
#undef MY_FANCY_PANTS_TABLE

Хотя я не уверен, нравится ли вам это.

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