Why not to use macros (#define) in modern C++

Bhushit Anjaria
3 min readFeb 22, 2021

--

Most of the people had changed their mobile phones classic nokia 3310 to a smartphones. Most of the people changes mobile phones every one or two year. Because newer phones have better performance, better feature, better technology then the older mobile phones.

Similar is with programming languages. Macros are legacy feature of “C” programming language which is carry forwarded to modern “C++” programming language.

I select an example of a classic ‘c’ language macros because Most of the projects which are converted to visual studio 6 to visual studio 2005 to visual studio 2017 to visual studio 2019 still uses macros. Even new code written still have macros.

What are disadvantages of using macros?

— > You cannot debug macros.

— >Macro do not have namespace so there are more chances for macro redefinition compiler warning

Most of the developer or reviewer came across a compiler warning C4005 which stands for macro redefinition.

Consider a situation where one developer has defined a macro viz.

namspace NAMESSPACE_A

{

#define SUCCESS 0

}.

Now a new developer started developing a code in which he require the same macro but do not know about the previously defined macro viz. SUCCESS, so he redefines a macro again in a different namespace

namspace NAMESSPACE_B

{

#define SUCCESS 1

}.

As we (C++ developers) know macros are preprocessor directives. Macros are replaced before the compilation process gets start. Compiler do not know about namespace when macros are being replaced by the compiler. So now in above example value of SUCCESS is changed to 1 i.e. last defined value of a macro in your code even though they are defined in different namespaces. This leads to an error as your old code is written considering value of SUCCESS as 0.

— >Macro can lead to strange side effects

Consider the macro #define SQUARE (number) ((number)*(number))

long nNumber= 4;

long nSquare = SQUARE(++nNumber);

This statement is evaluated into nSquare = ((5)*(6)) = 30;

So macro can lead to strange side effects

— >Different modules can have different value for same macro.

If we include a third party module in our code then it can have same macro name in the code, which leads to the erroneous result

Even Microsoft has released patches for macro redefinition warning, refer link given below

What should be the replacement for macros?

Macros are replaceable with enum class, const, inline, typedef, template and constexpr.

Even majority of static code analyzers give the warning/error stating that “Macros should not be used to define constant”

Refer below example taken from sonar source code analysis rule on how to replace macro with appropriate modern C++ language feature

Noncompliant Code Example

#define MAX_MEMORY 640 // Noncompliant#define LEFT   0 // Noncompliant
#define RIGHT 1 // Noncompliant
#define JUMP 2 // Noncompliant
#define SHOOT 3 // Noncompliant

Compliant Solution

constexpr size_t MAX_MEMORY = 640;
enum class Actions {Left, Right, Jump, Shoot};

Reference is also taken from C++ Core guidelines

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

--

--

No responses yet

Write a response