X-макрос

Идиома программирования C/C++

Макросы X — это идиоматическое использование макросов языка программирования для генерации списочных структур данных или кода. Они наиболее полезны, когда по крайней мере некоторые из списков не могут быть составлены индексированием, например, во время компиляции . Они обеспечивают надежное обслуживание параллельных списков, соответствующие элементы которых должны быть объявлены или выполнены в том же порядке.

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

Использование макросов X восходит к 1960-м годам. [1] Они остаются полезными в современных языках программирования C и C++ , но остаются относительно неизвестными. [2] [3]

Выполнение

Приложение X-макроса состоит из двух частей:

  1. Определение элементов списка.
  2. Расширение(я) списка для генерации фрагментов деклараций или утверждений.

Список определяется макросом или заголовочным файлом (называемым LIST), который сам по себе не генерирует никакого кода, а просто состоит из последовательности вызовов макроса (классически называемого " X") с данными элементов. Каждому расширению LISTпредшествует определение Xс синтаксисом для элемента списка. Вызов LISTрасширяется Xдля каждого элемента в списке.

Пример 1

В этом примере определяется список переменных и автоматически генерируются их объявления и функция для их вывода.

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

#define СПИСОК_ПЕРЕМЕННЫХ \  X(значение1) \  X(значение2) \  X(значение3)

Затем мы расширяем этот список, чтобы сгенерировать объявления переменных:

#define X(имя) int имя; СПИСОК_ПЕРЕМЕННЫХ #undef X

Аналогичным образом мы можем сгенерировать функцию, которая выводит переменные и их значения:

void print_variables ( void ) { #define X(имя) printf("%s = %d\n", #имя, имя); СПИСОК_ПЕРЕМЕННЫХ #undef X } 

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

int значение1 ; int значение2 ; int значение3 ;   void print_variables ( void ) { printf ( "%s = %d \n " , "значение1" , значение1 ); printf ( "%s = %d \n " , "значение2" , значение2 ); printf ( "%s = %d \n " , "значение3" , значение3 ); }          

Пример 2 с макросом X в качестве аргумента

Целью этого примера является улучшение читаемости использования макроса X путем:

  1. Добавьте префикс «FOR_» к имени макроса, определяющего список.
  2. Передать имя макроса-работника в макрос списка. Это позволяет избежать определения макроса с неясным именем (X) и устраняет необходимость его отмены.
  3. Используйте синтаксис для вариативных макроаргументов "..." в рабочих макросах, чтобы иметь возможность принимать больше аргументов, чем необходимо. Это позволяет сопровождающему код добавлять столбцы в список без необходимости обновления всех определений макросов.
  4. Используйте имя «DO» в качестве имени макроса, аргумента для макроса списка.


#define FOR_LIST_OF_VARIABLES(DO) \  DO(id1, name1) \  DO(id2, name2) \  DO(id3, name3) \

Как и выше, выполните этот список для генерации объявлений переменных:

#define DEFINE_NAME_VAR(id, name, ...) int name; ДЛЯ_СПИСКА_ПЕРЕМЕННЫХ ( DEFINE_NAME_VAR )  

или объявить перечисление:

#define DEFINE_ENUMERATION(id, name, ...) name = id, enum my_id_list_type { FOR_LIST_OF_VARIABLES ( DEFINE_ENUMERATION ) }     

Аналогичным образом мы можем сгенерировать функцию, которая выводит переменные и их имена:

void print_variables ( void ) { #define PRINT_NAME_AND_VALUE(id, name, ...) printf("%s = %d\n", #name, name); ДЛЯ_СПИСКА_ПЕРЕМЕННЫХ ( PRINT_NAME_AND_VALUE ) }   

Дальнейшее чтение

Ссылки

  1. ^ Мейерс, Рэнди. Новые макросы C: X. Dr.Dobb's 2001.
  2. ^ Брайт, Уолтер. X Macro. Цифровой Марс 2010
  3. ^ Лукас, Эндрю. Уменьшение ошибок кодирования на языке C с помощью макросов X. Embedded.com 2013
Взято с "https://en.wikipedia.org/w/index.php?title=X_macro&oldid=1268957455"