I want to replace
#define SomeValue ':'
with
static const uint8_t SomeValue = ':';
I am doubtful of this replace-with, is it correct to replace this macro with static const?
From Scott Meyers Effective C++
Item 1: Prefer const and inline to #define.
This Item might better be called "prefer the compiler to the preprocessor," because #define is often treated as if it's not part of the language per se. That's one of its problems. When you do something like this,
#define ASPECT_RATIO 1.653
the symbolic name ASPECT_RATIO may never be seen by compilers; it may be removed by the preprocessor before the source code ever gets to a compiler. As a result, the name ASPECT_RATIO may not get entered into the symbol table. This can be confusing if you get an error during compilation involving the use of the constant, because the error message may refer to 1.653, not ASPECT_RATIO. If ASPECT_RATIO was defined in a header file you didn't write, you'd then have no idea where that 1.653 came from, and you'd probably waste time tracking it down. This problem can also crop up in a symbolic debugger, because, again, the name you're programming with may not be in the symbol table.
The solution to this sorry scenario is simple and succinct. Instead of using a preprocessor macro, define a constant:
const double ASPECT_RATIO = 1.653;
In the same vein
From Herb Sutter, Andrei Alexandrescu C++ Coding Standards: 101 Rules, Guidelines, and Best Practices
16. Avoid macros
Macros remain the only solution for a few important tasks, such as #include guards #ifdef and #if defined for conditional compilation, and implementing assert.
For conditional compilation (e.g., system-dependent parts), avoid littering your code with #ifdefs. Instead, prefer to organize code such that the use of macros drives alternative implementations of one common interface, and then use the interface throughout.
You may want to use macros (cautiously) when the alternative is extreme copying and pasting snippets of code around.
Related
I have a macro definition in MyClass.h, stated as such:
#define _BufferSize_ 64
I placed the include directive for MyClass.h inside of main.cpp:
#include "MyClass.h"
Does this mean I can use _BufferSize_ in both main.cpp and MyClass.h? Also, is this good practice?
Yes, it would work. (Disregarding the problem with underscores that others have pointed out.)
Directive #include "MyClass.h" just copies the whole content of file MyClass.h and pastes it in the place of the #include. From the point of view of the compiler there is only one source file composed of the file specified by the user and all included files.
Having said that, it would be much better if you use in-language construction instead of preprocessor directive.
For example replace:
#define _BufferSize_ 64
with
constexpr size_t BufferSize = 64;
The only thing it does differently than the #define is that it specifies the type of the value (size_t in this case). Beside that, the second code will behave the same way and it avoids disadvantages of preprocessor.
In general, try to avoid using preprocessor directives. This is an old mechanism that was used when c++ coudn't do that things in-language yet.
Yes, that is the purpose of header files: creating declarations and constants in one file that you can "include" into translation units whenever you like.
However, your macro name is illegal, and a nice constexpr size_t BufferSize = 64 would be more idiomatic nowadays; even before recent versions of C++, a typed constant would be preferable to a macro in many cases.
First, regarding the identifier _BufferSize_, the standard states that:
3. ...some identifiers are reserved for use by C++ implementations and shall not be used otherwise; no diagnostic is required.
(3.1) Each identifier that contains a double underscore __ or begins with an underscore followed by an uppercase letter is reserved to the implementation for any use.
So having such an identifier in your code would lead to undefined behavior.
And as already suggested in the comments, using macro variables is not good practice in C++. You can use a const int instead.
Replying 3 years later because the answers are wrong and this is first google search result in certain keywords.
https://google.github.io/styleguide/cppguide.html#Preprocessor_Macros
Avoid defining macros, especially in headers; prefer inline functions, enums, and const variables. Name macros with a project-specific prefix. Do not use macros to define pieces of a C++ API.
Highlight by me, not in original text.
This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Why would someone use #define to define constants?
difference between a macro and a const in c++
C++ - enum vs. const vs. #define
What is the difference between using #define and const for creating a constant? Does any have a performance advantage over the other? Naturally I prefer using the const but I'm going to consider the #define if it has suitable advantages.
The #define directive is a preprocessor directive; the preprocessor replaces those macros by their body before the compiler even sees it. Think of it as an automatic search and replace of your source code.
A const variable declaration declares an actual variable in the language, which you can use... well, like a real variable: take its address, pass it around, use it, cast/convert it, etc.
Oh, performance: Perhaps you're thinking that avoiding the declaration of a variable saves time and space, but with any sensible compiler optimisation levels there will be no difference, as constant values are already substituted and folded at compile time. But you gain the huge advantage of type checking and making your code known to the debugger, so there's really no reason not to use const variables.
#define creates an entity for substitution by the macro pre-processor, which is quite different from a constant because depending on what you define it will or will not be treated as a constant. The contents of a #define can be arbitrarily complex, the classic example is like this:
#define SQR(x) (x)*(x)
Then later if used:
SQR(2+3*4)
That would be turned into:
(2+3*4)*(2+3*4)
The difference is that #define is processed by the preprocessor doing what amounts to simple text replacement. Const values defined like this are not visible for the actual compiler, while a variable defined with the const modifier is an actual typed "variable" (well not really that variable). The disadvantage of #define is that is replaces every occurence of the name, while const variables get normal lookup, so you have less risk of naming conflicts and it's not typesafe.
The advantage of #define is that it guarantees constness and therefore there will be no backing variable. Const Variables may or may not be substituted into the code, so #define might be faster in some situations. However a good compiler should inline those consts anyways and it's unlikely to make much of a difference in most situations, so I would keep using const unless you have a piece of code where you have seen that the compiler hasn't inlined the variable and it is very, very performance critical code.
#define is textual replacement, so it is as fast as it can get. Plus it guarantees constness. The downside is that it's not type-safe.
On the other hand, const variables may or may not be replaced inline in the code. You can cast away the constness, forcing it to be in memory (although it probably resides in read-only memory to begin with, but there's headaches either way). It is guaranteed to be type-safe though since it carries its own type with it.
I would personally recommend const to make your intent clear.
DEFINE is Preprocessor instruction, For example #define x 5. Compiler takes this value and insert is where ever you are calling x in the program and generate the object file. Define constants deosn't create a symbol entry in symbol table. IF you want to debug the program , you will not find x .
Use constant where ever possible that what i think.
#define A B tells the preprocessor (a part of the compiler) to substitude B wherever it sees A in the code, and it does it before compiling the code. You could (although it's a terrible idea) do something like #define FALSE TRUE.
A const variable means that once the variable is set it can't be changed, however it doesn't do anything with the preprocessor, and is subject to the normal rules of variables.
In Doom 3 source code, ID_INLINE macros is used instead of inline, which is declared as #define ID_INLINE inline. What reason there is to use this macro instead of simple inline?
For the same reason many other software packages uses a "inline macro". It serves two purposes:
It gives the programmer one simple place to "turn off all inlining" (which is very useful sometimes when debugging things) - and you can do it "per file" by doing #undef ID_INLINE followed by #define ID_INLINE - or change the overall macro to affect the entire project.
Some (old) compilers don't support standard inline keyword, or you may need to use special magic to convince the compiler to inline functions. So using an "inline macro" allows this to be changed for the whole project (at least if the programmers follow the coding standard).
With modern compilers, the former is certainly the main point.
The only reason for it is to have a way to redefine this macro as following, probably for debugging purposes:
#define ID_INLINE
I am reading the book C++ Coding Standards: 101 Rules, Guidelines, and Best Practices, and it says that using #define is bad to use. When I was looking at some of the header files they have many #defines. If it's bad to use #defines, why is there so many? Thank you.
#define are a bad practice because:
They don't have any Scope:
#defines don't respect scopes so there is no way to create a class scoped namespace. While variables can be scoped in classes.
Weird magical numbers during compilation errors:
If you are using #define those are replaced by the pre-processor at time of precompilation So if you receive an error during compilation, it will be confusing because the error message wont refer the macro name but the value and it will appear a sudden value, and one would waste lot of time tracking it down in code.
Debugging Problems:
Also for same reasons mentioned in #2, while debugging #define won't provide much of an help really.
Hence it is much better idea to use const variables instead of a #define.
They are superior to #define in all above mentioned aspects.Only areas where #define can be really helpful are where you need actual textual replacement in code or in defining include header guards.
Why are #definewidely used in C standard header files?
One reason that comes to my mind is, In C(unlike C++) const declarations do not produce constant expressions.Which means prior to introduction of Variable length arrays in C standard one cannot write something like:
const int max_val = 100;
int foos[max_val];
because in C max_val is not a compile time constant, and prior to introduction of VLA's array subscripts were needed to be compile time constants.
So one had to write this instead as:
#define MAX_VAL 100
int foos[MAX_VAL];
What that's probably referring to is the old C way of defining constants:
#define MAX_SOMETHING 100
int x = MAX_SOMETHING;
These constants aren't typed, they're expanded in place using a string substitution, and make it harder to debug since once the source is compiled it's not clear where that definition originated.
A more C++ way of doing it is:
const int max_something = 100;
int x = max_something;
Since this is a strongly typed value it is subject to all the required checks and appropriate conversions if required.
An additional benefit is that const values can be put into namespaces and classes for organizational purposes. A #define is global in scope so collisions are a concern, something that leads to awkwardly long names to avoid conflict.
Between const and template, which allows for a form of meta-programming C doesn't do natively, the number of occasions where #define is required is quite diminished. It's not entirely eliminated though, as without having the #import directive you will still need to add the old #ifndef __HEADER_FILE_NAME__ guards to ensure things aren't included twice.
The broad statment of the book is not so true - #define has its place for macro etc but for defining constants it is now not a good idea to use
eg
#define FOO 257
is better done at
const int FOO=257;
This allows type checking because with the #define this becomes a bit odd
char c=FOO;
This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
Why would someone use #define to define constants?
difference between a macro and a const in c++
C++ - enum vs. const vs. #define
What is the difference between using #define and const for creating a constant? Does any have a performance advantage over the other? Naturally I prefer using the const but I'm going to consider the #define if it has suitable advantages.
The #define directive is a preprocessor directive; the preprocessor replaces those macros by their body before the compiler even sees it. Think of it as an automatic search and replace of your source code.
A const variable declaration declares an actual variable in the language, which you can use... well, like a real variable: take its address, pass it around, use it, cast/convert it, etc.
Oh, performance: Perhaps you're thinking that avoiding the declaration of a variable saves time and space, but with any sensible compiler optimisation levels there will be no difference, as constant values are already substituted and folded at compile time. But you gain the huge advantage of type checking and making your code known to the debugger, so there's really no reason not to use const variables.
#define creates an entity for substitution by the macro pre-processor, which is quite different from a constant because depending on what you define it will or will not be treated as a constant. The contents of a #define can be arbitrarily complex, the classic example is like this:
#define SQR(x) (x)*(x)
Then later if used:
SQR(2+3*4)
That would be turned into:
(2+3*4)*(2+3*4)
The difference is that #define is processed by the preprocessor doing what amounts to simple text replacement. Const values defined like this are not visible for the actual compiler, while a variable defined with the const modifier is an actual typed "variable" (well not really that variable). The disadvantage of #define is that is replaces every occurence of the name, while const variables get normal lookup, so you have less risk of naming conflicts and it's not typesafe.
The advantage of #define is that it guarantees constness and therefore there will be no backing variable. Const Variables may or may not be substituted into the code, so #define might be faster in some situations. However a good compiler should inline those consts anyways and it's unlikely to make much of a difference in most situations, so I would keep using const unless you have a piece of code where you have seen that the compiler hasn't inlined the variable and it is very, very performance critical code.
#define is textual replacement, so it is as fast as it can get. Plus it guarantees constness. The downside is that it's not type-safe.
On the other hand, const variables may or may not be replaced inline in the code. You can cast away the constness, forcing it to be in memory (although it probably resides in read-only memory to begin with, but there's headaches either way). It is guaranteed to be type-safe though since it carries its own type with it.
I would personally recommend const to make your intent clear.
DEFINE is Preprocessor instruction, For example #define x 5. Compiler takes this value and insert is where ever you are calling x in the program and generate the object file. Define constants deosn't create a symbol entry in symbol table. IF you want to debug the program , you will not find x .
Use constant where ever possible that what i think.
#define A B tells the preprocessor (a part of the compiler) to substitude B wherever it sees A in the code, and it does it before compiling the code. You could (although it's a terrible idea) do something like #define FALSE TRUE.
A const variable means that once the variable is set it can't be changed, however it doesn't do anything with the preprocessor, and is subject to the normal rules of variables.