static const vs #define

Viewed 179738

Is it better to use static const vars than #define preprocessor? Or maybe it depends on the context?

What are advantages/disadvantages for each method?

11 Answers

#define can lead to unexpected results:

#include <iostream>

#define x 500
#define y x + 5

int z = y * 2;

int main()
{
    std::cout << "y is " << y;
    std::cout << "\nz is " << z;
}

Outputs an incorrect result:

y is 505
z is 510

However, if you replace this with constants:

#include <iostream>

const int x = 500;
const int y = x + 5;

int z = y * 2;

int main()
{
    std::cout << "y is " << y;
    std::cout << "\nz is " << z;
}

It outputs the correct result:

y is 505
z is 1010

This is because #define simply replaces the text. Because doing this can seriously mess up order of operations, I would recommend using a constant variable instead.

Always prefer to use the language features over some additional tools like preprocessor.

ES.31: Don't use macros for constants or "functions"

Macros are a major source of bugs. Macros don't obey the usual scope and type rules. Macros don't obey the usual rules for argument passing. Macros ensure that the human reader sees something different from what the compiler sees. Macros complicate tool building.

From C++ Core Guidelines

As a rather old and rusty C programmer who never quite made it fully to C++ because other things came along and is now hacking along getting to grips with Arduino my view is simple.

#define is a compiler pre processor directive and should be used as such, for conditional compilation etc.. E.g. where low level code needs to define some possible alternative data structures for portability to specif hardware. It can produce inconsistent results depending on the order your modules are compiled and linked. If you need something to be global in scope then define it properly as such.

const and (static const) should always be used to name static values or strings. They are typed and safe and the debugger can work fully with them.

enums have always confused me, so I have managed to avoid them.

Related