2015-09-02 4 views
6

Согласно cplusplus.com, синтаксис для определения макроса:Препроцессор макросов без замены C++

#define identifier replacement 

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

#define afx_msg   // intentional placeholder 

Мои вопросы:

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

Когда вы пробовали это, пшеницу вы обнаружили? –

+0

Вы можете просто подумать о '# define' как о простой функции поиска и замены, примененной перед компиляцией. Просто попробуйте выполнить поиск afx_msg и замените их ничем. – Catalin

ответ

10

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

Существует несколько причин, по которым вы использовали бы что-то подобное. Один из них - просто использовать макрос в #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(); 

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

1
  1. препроцессор обрабатывает его, удаляя его и заменить его ничем
  2. может быть множество причин, в том числе читаемости, переносимости, пользовательских функций компилятора и т.д.
3
#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 

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

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

Смежные вопросы