Is it better to use static const
vars than #define
preprocessor? Or maybe it depends on the context?
What are advantages/disadvantages for
Please see here: static const vs define
usually a const declaration (notice it doesn't need to be static) is the way to go
Pros and cons between #define
s, const
s and (what you have forgot) enum
s, depending on usage:
enum
s:
enum class X
are disambiguated by the scope X::
int
but can be explicitly set by the programmertemplate <typename T> void f(T t) { cout << ++t; }
won't compile, though you can wrap an enum into a class with implicit constructor, casting operator and user-defined operators)template <typename T> void f(T)
get a distinct instantiation when passed the same numeric value from different enums, all of which are distinct from any actual f(int)
instantiation. Each function's object code could be identical (ignoring address offsets), but I wouldn't expect a compiler/linker to eliminate the unnecessary copies, though you could check your compiler/linker if you care.enum { A = 1, B = 2 }
- is A|B
"legal" from a program logic perspective?)make
and other timestamp-based recompilation tools will trigger client recompilation when they're changed (bad!)const
s:
#define
ala #define S std::string("abc")
, but the constant avoids repeated construction of distinct temporaries at each point of useconst
value, which minimises work and impact if switching between the two#define
s:
#define X "x"
and some client usage ala "pre" X "post"
, if you want or need to make X a runtime-changeable variable rather than a constant you force edits to client code (rather than just recompilation), whereas that transition is easier from a const char*
or const std::string
given they already force the user to incorporate concatenation operations (e.g. "pre" + X + "post"
for string
)sizeof
directly on a defined numeric literalunsigned
){ 1, 2 }
that can be used to initialise arrays, or #define MICROSECONDS *1E-6
etc. (definitely not recommending this!)__FILE__
and __LINE__
can be incorporated into the macro substitution#if
statements for conditionally including code (more powerful than a post-preprocessing "if" as the code need not be compilable if not selected by the preprocessor), use #undef
-ine, redefine etc.make
and other timestamp-based recompilation tools will trigger client recompilation when they're changed (bad!)My personal opinion:
As a general rule, I use const
s and consider them the most professional option for general usage (though the others have a simplicity appealing to this old lazy programmer).
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.
Using a static const is like using any other const variables in your code. This means you can trace wherever the information comes from, as opposed to a #define that will simply be replaced in the code in the pre-compilation process.
You might want to take a look at the C++ FAQ Lite for this question: http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.7