8

Macros are considered a good thing by one and evil by another.

Is there a rule of thumb when to and when not to use macros in C++?

When are macros idiomatic and when should they be avoided?

6
  • 3
    stackoverflow.com/q/96196 Commented Jun 29, 2015 at 18:21
  • @RobertHarvey Should I conclude I should only use macros if there is no way around them? Commented Jun 29, 2015 at 18:24
  • 1
    @Mast That's my understanding, yes. The only uses of macros that I'd consider unobjectionable in C++ would be logging and assertions, because __FILE__ and __LINE__ are very, very useful things for logger and assertion output to have. Commented Jun 29, 2015 at 18:31
  • 2
    Also, include guards. While #pragma once is nice, it is nonstandard. Commented Jun 29, 2015 at 19:44
  • 2
    In addition to the aforementioned situations, compiler-vendor specific variations in keywords such as restrict, export (from a static or dynamic library), and inline / noinline also requires the use of conditional compilation macros. Workarounds for missing C++11 support in some compilers would also require conditional compilation macros. Commented Jun 30, 2015 at 10:33

3 Answers 3

14

When are macros idiomatic and when should they be avoided?

Macros are idiomatic only when there is no alternative to their use. Examples are include guards (they are the only portable form), embedded domain-specific languages, special compiler support not available through other language features (embedding built-in macros like __FILE__, stringifying and concatenating identifiers), and a few other places.

Macros should be avoided whenever possible. That's because they follow their own very simplistic syntax and know nothing about C++, dumbly trampling over any and all namespaces.

It has always been one of Stroustrup's goals to eliminate the preprocessor as much as possible. Function inlining, templates, and constants are a prime example, as are modules (to replace #include), which have been chewed on by the standardization committee for years. The language features created to avoid having to use macros are all very much better than the macros they replace. Make use of them whenever possible.

15

As a rule, you should only use macros, when a better alternative does not exist.

They should not be used to generate code; you should simply write the code instead (if the code is type-agnostic, write a template instead).

They should not be used to define constants; constants should be defined using one of these: (static) constexpr/const variables, anonymous enumerations, named enumerations, enum classes (depending on what you want to use them for).

They should be used for conditional compilation (include guards are one of these cases).

Ideally, they should not be used to conditionally change the API of a module at compilation (that is, ideally you should declare the same functions in all configurations, then use conditional compilation in the implementation file.

In all* other cases, macros should be avoided.


(*) - Sometimes, there are exceptions to "all other cases" (for example, you may have third party code that requires you to use macros; that's life :-) ).

1
  • Sometimes a short set of macros (with #undef immediately after use!) is the right way to generate sets of function bodies. Case in point: JVM bytecode instruction struct with serializer & parser - if you have suggestions to make that more maintainable without the macros, then please add a review there with your advice. Commented Jul 6, 2023 at 7:05
3

The only time I'd consider macros are for compile time constants, typically ones that affect the compilation (as opposed to constant application values, which are better modelled as const types).

However, I have modelled utility routines such as calls to logging functions in a macro just so they will be compiled out, but I think even this is unnecessary today - the compiler should be clever enough to realise a logging function that does nothing due to conditional compilation will be optimised away, but old habits die hard :)

1
  • In C++11 and newer, they shouldn't be used for compile-time constants either since that's what constexpr is fo. Commented Jul 1, 2015 at 9:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.