c препроцессор: арифметика c в конкатенации - PullRequest
0 голосов
/ 27 января 2020

как я могу заставить препроцессор выполнять арифметику c в конкатенации?
Я пробовал:

#define DECL_FUNCT3(ch1, ch2) \
        void funct_ ## ch1 ## _and_ ## ch2 ## _(void);

#define DECL_FUNCT2(ch1, ch2) DECL_FUNCT3(ch1, ch2)
#define DECL_FUNCT1(ch1, ch2) DECL_FUNCT2(ch1, ch2)
#define DECL_FUNCT(ch) DECL_FUNCT1(ch, ch+16)

DECL_FUNCT(0)
DECL_FUNCT(1)

Я хотел бы получить:

void funct_0_and_16_(void);
void funct_1_and_17_(void);

но я получаю:

$ gcc -E test.c 
[...]
void funct_0_and_0+16_(void);
void funct_1_and_1+16_(void);

Возможно ли это?

Ответы [ 3 ]

3 голосов
/ 27 января 2020

Если ch находится в диапазоне от 0 до 240, вы можете использовать BOOST_PP_ADD из библиотеки форсированного препроцессора для этого:

#include <boost/preprocessor/arithmetic/add.hpp>

#define DECL_FUNCT3(ch1, ch2) \
        void funct_ ## ch1 ## _and_ ## ch2 ## _(void);

#define DECL_FUNCT2(ch1, ch2) DECL_FUNCT3(ch1, ch2)
#define DECL_FUNCT1(ch1, ch2) DECL_FUNCT2(ch1, ch2)
#define DECL_FUNCT(ch) DECL_FUNCT1(ch, BOOST_PP_ADD(ch,16))

DECL_FUNCT(0)
DECL_FUNCT(240)

Демонстрация Godbolt (использует C ++, но должен работать и для C):

https://godbolt.org/z/2edrua (это определяет пустые функции, вместо того, чтобы объявлять их для получения видимого вывода сборки).

3 голосов
/ 27 января 2020

Нет. Это невозможно.

Препроцессор C выполняет только текстовые замены. Единственное место, где вычисляет препроцессор, это как в #if 10 + 20 == 30, но эта строка не выполняет никаких замен.

0 голосов
/ 27 января 2020

Существует обходной путь для вашего конкретного случая c: используйте шестнадцатеричные числа в именах.

Измените 2 макроса:

#define DECL_FUNCT3(ch1, ch2) \
        void funct_0 ## ch1 ## h_and_1 ## ch2 ## h_(void);
...
#define DECL_FUNCT(ch) DECL_FUNCT1(ch, ch)

И вы получите:

void funct_00h_and_10h_(void);
void funct_01h_and_11h_(void);

Существуют некоторые ограничения:

  • Разница между двумя числами должна составлять 16.
  • Работает только для чисел 00h..0fh и 10h..1fh.
...