The C preprocessor is justifiably feared and shunned by the C++ community. In-lined functions, consts and templates are usually a safer and superior alternative to a #define
.
The following macro:
#define SUCCEEDED(hr) ((HRESULT)(hr) >= 0)
is in no way superior to the type safe:
inline bool succeeded(int hr) { return hr >= 0; }
But macros do have their place, please list the uses you find for macros that you can't do without the preprocessor.
Please put each use-cases in a seperate answer so it can be voted up and if you know of how to achieve one of the answers without the preprosessor point out how in that answer's comments.
Mostly:
__LINE__
and__FILE__
)Seems VA_ARGS have only been mentioned indirectly so far:
When writing generic C++03 code, and you need a variable number of (generic) parameters, you can use a macro instead of a template.
Note: In general, the name check/throw could also be incorporated into the hypothetical
get_op_from_name
function. This is just an example. There might be other generic code surrounding the VA_ARGS call.Once we get variadic templates with C++11, we can solve this "properly" with a template.
As wrappers for debug functions, to automatically pass things like
__FILE__
,__LINE__
, etc:Header file guards necessitate macros.
Are there any other areas that necessitate macros? Not many (if any).
Are there any other situations that benefit from macros? YES!!!
One place I use macros is with very repetitive code. For example, when wrapping C++ code to be used with other interfaces (.NET, COM, Python, etc...), I need to catch different types of exceptions. Here's how I do that:
I have to put these catches in every wrapper function. Rather than type out the full catch blocks each time, I just type:
This also makes maintenance easier. If I ever have to add a new exception type, there's only one place I need to add it.
There are other useful examples too: many of which include the
__FILE__
and__LINE__
preprocessor macros.Anyway, macros are very useful when used correctly. Macros are not evil -- their misuse is evil.
Let's say we'll ignore obvious things like header guards.
Sometimes, you want to generate code that needs to be copy/pasted by the precompiler:
which enables you to code this:
And can generate messages like:
Note that mixing templates with macros can lead to even better results (i.e. automatically generating the values side-by-side with their variable names)
Other times, you need the __FILE__ and/or the __LINE__ of some code, to generate debug info, for example. The following is a classic for Visual C++:
As with the following code:
it generates messages like:
Other times, you need to generate code using the # and ## concatenation operators, like generating getters and setters for a property (this is for quite a limited cases, through).
Other times, you will generate code than won't compile if used through a function, like:
Which can be used as
(still, I only saw this kind of code rightly used once)
Last, but not least, the famous
boost::foreach
!!!(Note: code copy/pasted from the boost homepage)
Which is (IMHO) way better than
std::for_each
.So, macros are always useful because they are outside the normal compiler rules. But I find that most the time I see one, they are effectively remains of C code never translated into proper C++.
Some very advanced and useful stuff can still be built using preprocessor (macros), which you would never be able to do using the c++ "language constructs" including templates.
Examples:
Making something both a C identifier and a string
Easy way to use variables of enum types as string in C
Boost Preprocessor Metaprogramming