Макрос препроцессора без замены С++

Согласно cplusplus.com, синтаксис для определения макроса:

#define identifier replacement

Однако иногда я натыкаюсь на определение макроса, которое не содержит замены. Например, в файле afxwin.h существует следующее определение препроцессора:

#define afx_msg // intentional placeholder

Мои вопросы:

  • Что происходит во время компиляции, когда используется определение препроцессора, которое не имеет замены? Это просто игнорируется? Например, линия afx_msg void OnAddButton(); станет void OnAddButton();?
  • Какова цель использования препроцессора без замены? Это просто сделать код более понятным?
3 ответа

"Ничего" (без текста) является допустимым текстом замены для макроса. Он будет просто удален (точнее, заменен ничем) препроцессором.

Существует несколько причин, по которым вы будете использовать что-то вроде этого. Один из них - просто использовать макрос в #ifdef и подобных конструкторах.

Другой - условная компиляция. Типичным примером использования являются публичные API и экспорт DLL. В Windows вам нужно отметить функцию, экспортированную из DLL (при создании DLL) или импортированную из DLL (при связывании с DLL). В системах ELF таких деклараций не требуется. Поэтому в заголовках публичной библиотеки вы часто увидите такой код:

#ifdef _WIN32
 #ifdef BUILDING_MYLIB
 #define MYLIB_API __declspec(dllexport)
 #else
 #define MYLIB_API __declspec(dllimport)
 #endif
#else
 #define MYLIB_API
#endif
void MYLIB_API myApiFunction();

Еще одна причина может быть инструментом обработки кода. Возможно, у вас есть инструмент, который анализирует исходный код, извлекая список функций с определенным маркером. Вы можете определить такой маркер как пустой макрос.


#define bla

просто определяет bla.

вы можете использовать его с помощью

#ifdef bla
...
place some code here
...
#endif

типичным вариантом использования является #define DEBUG, чтобы включить специальные части кода в режиме отладки.

Другой способ установить такие вещи из "снаружи":

g++ -DDEBUG x.cpp

который также устанавливает макрос DEBUG.

И каждый заголовочный файл должен иметь что-то вроде:

#ifndef THIS_HEADER_INCLUDE_GUARD
#define THIS_HEADER_INCLUDE_GUARD
...
rest of header file
...
#endif

Это просто защищает ваш файл заголовка для (рекурсивно) более одного раза.

Некоторые могут быть выполнены с конкретными реализацией #pragma once.


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

licensed under cc by-sa 3.0 with attribution.