Как я могу оценить арифметическое выражение макрос-функции для перехода к другой макрос-функции в препроцессоре C?

как я могу заставить этот пример кода работать? (На C или C ++)

Cout только для примера. Я хочу оценить правильное уменьшенное число

#define PRINT_1 std::cout<<"One : " <<1;
#define PRINT_2 std::cout<<"Two : " <<2;

#define DEC_AND_PRINT(number) PRINT_##number-1

Когда я звоню DEC_AND_PRINT(3), я ожидаю этого:

DEC_AND_PRINT(3)  PRINT_##(3-1) -> PRINT_2 -> std::cout<<"Two : "<<2

Но компилятор выдает ошибку:

GCC: ошибка: 'PRINT_3' не был объявлен в этой области ...

GCC: примечание: в раскрытии макроса 'DEC_AND_PRINT' DEC_AND_PRINT (3)

Как я могу уменьшить аргумент?

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


person Diego Teixeira de Souza    schedule 04.10.2017    source источник
comment
PRINT_1 std::cout<<"One : " <<1; не будет работать в C. Удаление тега C.   -  person chux - Reinstate Monica    schedule 04.10.2017
comment
Вы не можете. Препроцессор так использовать нельзя.   -  person user207421    schedule 04.10.2017
comment
Спасибо.   -  person Diego Teixeira de Souza    schedule 04.10.2017
comment
Вы не можете заставить его работать на C; std::cout << нотация по своей сути C ++ и только C ++.   -  person Jonathan Leffler    schedule 04.10.2017
comment
Вероятно, это дубликат Как именно трюк с двойной строкой работать? (или другой подобный вопрос). Вам нужно использовать дополнительный уровень макро-косвенного обращения, чтобы оценить 3-1 до его окончательного значения 2.   -  person Cornstalks    schedule 04.10.2017
comment
@DiegoTeixeiradeSouza Поскольку это препроцессор, вам нужно быть кристально чистым и конкретным. Невозможно, чтобы EVAL(11+22*3) расширялся до 77, но EVAL(11+3*3) расширялся до 20. Возможно, но необходимо, чтобы ADD(11,MUL(22,3)) расширился до 77. Довольно просто заставить ваш макрос работать (нужно DEC_AND_PRINT(3) оценить PRINT_2). Что вам нужно?   -  person H Walters    schedule 04.10.2017
comment
@Cornstalks Косвенное обращение не поможет; макросы не оценивают выражения. Условные директивы (_1 _ / _ 2_) могут, но не макросы.   -  person H Walters    schedule 04.10.2017
comment
@HWalters: Вот дерьмо, ты прав. Я смешивал расширение макроса и оценку макроса. Спасибо что подметил это.   -  person Cornstalks    schedule 05.10.2017


Ответы (1)


Спасибо за все.

Нет способа делать то, что я хочу. Препроцессор не может вычислить выражение и использовать результат в конкатенации ##.

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

ВЫЗОВ DefinePointer (T)

DefinePointer_1 (T)

Определить T * -> Вызвать DefinePointer_2 (T *)

                DefinePointer_2( T*)
                Define T**  -> Call DefinePointer_3(T**)
                                    DefinePointer_3(T**)
                                  Define T*** -> Call DefinePointer_4(T****)                     

Это всего лишь фрагмент кода, но это еще не все. Мне пришлось много писать, но в конце концов это сработало, и можно было писать алгоритмы и структуры данных для любого типа данных.

person Diego Teixeira de Souza    schedule 04.10.2017
comment
Фактически, препроцессор может оценивать выражение и использовать результат в конкатенации. Вы просто не можете создать макрос, который оценивает выражение. - person H Walters; 05.10.2017