A.P.
A.P.

Reputation: 481

Preprocessor macro without replacement C++

According to cplusplus.com, the syntax to define a macro is:

#define identifier replacement

However, I sometimes stumble upon a macro definition which doesn't contain a replacement. For example in afxwin.h, there is the following preprocessor definition:

#define afx_msg         // intentional placeholder

My questions:

  1. What happens at compile-time when a preprocessor definition that doesn't have a replacement is used? Is it simply ignored? For example, does the line afx_msg void OnAddButton(); become void OnAddButton();?
  2. What is the purpose of using preprocessor without replacement? Is it simply to make code more clear?

Upvotes: 8

Views: 1647

Answers (3)

Klaus
Klaus

Reputation: 25663

#define bla

simply defines bla.

you can use it with

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

a typical use case is #define DEBUG to enable special code parts in debugging mode.

Another way to set such things from "outside" is:

 g++ -DDEBUG x.cpp

which also sets the macro DEBUG defined.

And every header file should have something like:

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

This simply protects your header file for (recursivly) read more the once.

Some can be done with implementation specific #pragma once.

Upvotes: 5

"Nothing" (no text) is a valid replacement text for a macro. It will simply be removed (more precisely, replaced by nothing) by the preprocessor.

There are multiple reasons why you'd use something like this. One is to simply use the macro in #ifdef and similar constructrs.

Another is conditional compilation. A typical use case is public APIs and DLL exports. On Windows, you need to mark a function as exported from a DLL (when building the DLL) or as imported from a DLL (when linking against the DLL). On ELF systems, no such declarations are necessary. Therefore, you'll often see code like this in public library headers:

#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();

Yet another reason could be code processing tools. Perhaps you have a tool which parses source code, extracting a list of functions with a certain marker. You can define such a marker as an empty macro.

Upvotes: 13

mark
mark

Reputation: 5469

  1. the preprocessor processes it, removing it and replacing it with nothing
  2. could be a variety of reasons, including readability, portability, custom compiler features, etc.

Upvotes: 1

Related Questions