Варіативний макросВаріати́вний ма́крос — можливість препроцесором Сі за допомогою спеціального макроса оголошувати підтримку різного числа аргументів. Макрос зі змінним числом аргументів представлено 1999 року в ревізії ISO/IEC 9899:1999 (C99) стандарту мови програмування C. Також такі макроси 2011 року введено в ревізію ISO/IEC 14882:2011 (C++11) стандарту мови програмування C++[1]. Синтаксис оголошенняСинтаксис оголошення схожий зі синтаксисом варіативної функції: пропуск «...» використовується для позначення того, що можна передати нуль або більше аргументів. При розширенні макросом, кожен виклик спеціального ідентифікатора __VA_ARGS__ у списку заміщення макроса замінюється переданими аргументами. Доступ до індивідуальних аргументів у списку формальних параметрів не здійснюється ні за значенням, ні за способом, яким їх передано. У gcc у списку формальних параметрів макроса можуть бути як позначені аргументи (англ. specified arguments), так і передані варіативно (див. приклад). ПідтримкаGNU Compiler Collection, починаючи з версії 3.0, C++ Builder 2006 і Visual Studio 2005 [1] [Архівовано 8 квітня 2008 у Wayback Machine.] підтримують макроси зі змінним числом аргументів при компіляції коду як мовою C, так і мовою C++. Крім того, GCC підтримує варіативні макроси при компіляції коду мовою Objective-C. ПрикладЯкщо потрібно printf-подібній функції dprintf(), що приймає ім'я файлу і номер рядка, з якого викликається як аргумент, можна використати такий макрос: void realdprintf (char const *file, int line, char const *fmt, ...);
#define dprintf(...) realdprintf(__FILE__, __LINE__, __VA_ARGS__)
dprintf() можна викликати як: dprintf("Hello, world");
який доповнюється до: realdprintf(__FILE__, __LINE__, "Hello, world");
або: dprintf("%d + %d =%d", 2, 2, 5);
який доповнюється до:
realdprintf(__FILE__, __LINE__, "%d + %d =%d", 2, 2, 5);
АльтернативиУ деяких випадках альтернативою варіативним макросам може стати звичайний макровиклик. Наприклад, такий код можна використати для налагодження: #ifdef TRACING
#define TRACE(_p) printf _p
#else
#define TRACE(_p)
#endif
Якщо макрос TRACING визначено під час компіляції, виклик макроса TRACE буде еквівалентним виклику функції printf: TRACE(("Виконується рядок %d\n", __LINE__));
Якщо макрос TRACING не визначено, під час роботи програми повідомлення не друкуватиметься. Зверніть увагу, що параметри виклику цього макроса слід укласти в подвійні дужки. У деяких інших випадках замість варіативних макросів можна використати функціонал stdargs мов C/C++ і виклик функції vprintf. Інший приклад: #if defined ( DEBUG_MCU )
#define TRACE( args ... ) printf( args )
#else
#define TRACE( args ... )
#endif
Див. такожПримітки
Джерела |
Portal di Ensiklopedia Dunia