#define was changed to constexpr auto [duplicate] - c++

This question already has answers here:
Is it bad practice to specify an array size using a variable instead of `#define` in C++? (C error: variably modified at file scope) [closed]
(3 answers)
Closed 3 years ago.
I defined some code in c++, ex:
#define array_width 3;
Visual Studio will suggest changing to:
constexpr auto array_width = 3;
what's the reason to change? and what is the benefit?
Thanks.

The main reason for these suggestions is that the preprocessor does nothing but simple textual replacement (no type checking or similar things a compiler performs). There are many potential pitfalls when using the preprocessor - when you can avoid it, do so. `constexpr´ is one of the building blocks that allow for fewer macros these days.
To back this with an authority: From S. Meyers, Effective C++, Item 2 ("Prefer consts, enums, and inlines to #defines"):
Things to Remember
For simple constants, prefer const objects or enums to #defines
[...]
From S. Meyers, Effective Modern C++, Item 15 ("Use constexpr whenever possible"):
Things to Remember
constexpr objects are const and are initialized with values known during
compilation.
[...]
constexpr objects and functions may be used in a wider range of contexts than non-constexpr objects and functions.

Macros work by substituting text. With macro the following example code will be ill-formed:
struct foo
{
int array_width{};
};
So in modern C++ one should prefer to avoid macros when there are alternatives available. Also it is a good idea to use UNIQUE_PREFIX_UPPER_CASE naming convention for macros to avoid possible clashes with normal code.

Related

prevent hard coded numbers in C++

How may I prevent hard coded numbers in C++?
For example if I have Score+=10;
In C I would do:
#define FACTOR 10
Score+=FACTOR
But In C++ my professor told we don't use #define anymore (It's a C thing and risky), So what should I use?
You can use enum or const int, but I see nothing wrong with #define in that particular example and I prefer to use #define
I hope your professor is allowing you to use C++17/20 or at least C++11.
If that's the case, you best use constexpr for every constant.
constexpr auto FACTOR = 10;
From C++17 on, you can even use this to create classes as constants within class/struct scope without ODR violations.
struct S
{
constexpr static std::string_view STR = "str"sv;
};
1.Doesn't belong to namespaces, and cannot be kept in namespaces.
macro named "max" (as windows.h does), and you try to use std::max(a,b), then at least some compilers will still do macro substitution, giving something like std::(a<b?b:a),
2.Debugging is Difficult in #define since it is a pre processor runs before the execution of code.

Does auto do something complete different in C++ as in C?

After reading this post: Is there a downside to declaring variables with auto in C++?
I was asking myself: Is really no one of the answerers aware of auto not beeing a type but a storage-class specifier.
Or is auto since C++11 something different as the storage-class specifier in plain C?
If so, does this break the compability between C and C++?
(I'm aware that they official never were supporting each other in anyway, but my experience was that the C++ comittee tryed to stay as close to C as possible when evver it was acceptable. But now changing an obsolete, but abyway existing keyword instead of just adding a new one. Why here doing such a break of consistens?)
As of c++11 auto means to infer the type. It was used because adding a new keyword would have caused more c++ programs to break. As a storage specifier, auto is useless because it is the default if no specifier is added.
The only alternative was to follow the approach used in C generics of using a name starting with an underscore. This would have lead to an ugly keyword, that is meant to be regularly used.

beginner MACRO vs. const conceptual idea [duplicate]

This question already has answers here:
Inline functions vs Preprocessor macros
(14 answers)
C/C++ macros instead of const [duplicate]
(4 answers)
Closed 7 years ago.
What is the most significant difference of these two max operations? Which one do
you prefer to use in your system, and why?
#define max(a,b) (a)<(b)?(b):(a)
int max (const int a, const int b) { return (a) < (b) ? (b) : (a); }
I am trying to see if I am on the right track for the above question. My first thought is obviously that the #define indicates a preprocessor directive, or MACRO, named "max". Therefore, anywhere "max" is encountered in the program, it will be replaced with the defined value of this macro. Macros also dont require any memory allocation, so we can expect faster execution times.
The const keyword, on the other hand, does require memory allocation, and is not able to be changed by the executing program. The overall consensus through my notes and some online sources seems to be that macros are more efficient/faster since they do not require the memory allocation. Therefore, it would seem I would prefer to use macros for their speed advantages.
Basically my question is, am I nailing the main differences between these two? Or am I missing something major?

C/C++ macros instead of const [duplicate]

This question already has answers here:
What is the difference between #define and const? [duplicate]
(6 answers)
Closed 9 years ago.
The macro #define MAX 80 is equivalent to const int MAX = 80; Both are constant and cannot be modified.
Isn't it better to use the macro instead of the constant integer? The constant integer takes memory. The macro's name is replaced by its value by the pre-processor, right? So it wouldn't take memory.
Why would I use const int rather than the macro?
Reason #1: Scoping. Macros totally ignore scope.
namespace SomeNS {
enum Functor {
MIN = 0
, AVG = 1
, MAX = 2
};
}
If the above code happens to be included in a file after the definition of the MAX macro, it will happily get preprocessed into 80 = 2, and fail compiling spectacularly.
Additionally, const variables are type safe, can be safely initialised with constant expressions (without need for parentheses) etc.
Also note that when the compiler has access to the const variable's definition when using it, it's allowed to "inline" its value. So if you never take its address, it does no even need not take up space.
There are a few reasons actually :
Scoping : you can't define a scope for a macro. It is present at global scope, period. Thus you can't have class-specific constants, you can't have private constants, etc. Also, you could end up with name collision, if you end up declaring something with the same name of a macro that you don't even know exists (in some lib/header you included f.e.)
Debugging : as the preprocessor just replaces instances of the macro with its value, it can become tricky to know why you got an error with a specific value (or just a specific behavior that you didn't expect...) . You have to remember where this value comes from. It is even more important in the case of reusable code, as you can even don't understand where does a value comes from, if it has been defined as a macro in a header you didn't write (thus it's not very good to do this yourself)
Adresses : a const variable is, well, a variable. It means notably that you can pass its adress around (when const pointers or const reference are needed), but you can't with macro
Type safety : you can specify a type for a const variable, something you can't for a macro.
As a general rule, I'd say that (in my opinion) you should avoid #define directives when you have a clear alternative (i.e. const variables, enums, inlines).
The thing is they aren't the same. The macro is just text substitution by the preprocessor while the const is a normal variable.
If someone ever tries to shadow MAX within a function (like const in MAX = 32;) they get a really weird error message when MAX is a macro.
In C++ the language-idiomatic approach is to use constants rather than macros. Trying to save a few bytes of memory (if it even saves them) doesn't seem worth the cost in readability.
1) Debugging is the main one for me. It's difficult for a debugger to resolve MAX to the value at run time, but it can do it with the const int version.
2) You don't get any type information with #define. If you're using a template-based function; say std::max where your other datum is a const int then the macro version will fail but the const int version will not. To work around that you'd have to use #define MAX 80U which is ugly.
3) You cannot control scoping with #define; it will apply to the whole compilation unit following the #define statement.

What are the major advantages of const versus #define for global constants?

In embedded programming, for example, #define GLOBAL_CONSTANT 42 is preferred to const int GLOBAL_CONSTANT = 42; for the following reasons:
it does not need place in RAM (which is usually very limited in microcontrollers, and µC applications usually need a large number of global constants)
const needs not only a storage place in the flash, but the compiler generates extra code at the start of the program to copy it.
Against all these advantages of using #define, what are the major advantages of using const?
In a non-µC environment memory is usually not such a big issue, and const is useful because it can be used locally, but what about global constants? Or is the answer just "we should never ever ever use global constants"?
Edit:
The examples might have caused some misunderstanding, so I have to state that they are in C. If the C compiler generated the exact same code for the two, I think that would be an error, not an optimization.
I just extended the question to C++ without thinking much about it, in the hopes of getting new insights, but it was clear to me, that in an object-oriented environment there is very little space for global constants, regardless whether they are macros or consts.
Are you sure your compiler is too dumb to optimize your constant by inserting its value where it is needed instead of putting it into memory? Compilers usually are good in optimizations.
And the main advantage of constants versus macros is that constants have scope. Macros are substituted everywhere with no respect for scope or context. And it leads to really hard to understand compiler error messages.
Also debuggers are not aware of macros.
More can be found here
The answer to your question varies for C and C++.
In C, const int GLOBAL_CONSTANT is not a constant in C, So the primary way to define a true constant in C is by using #define.
In C++, One of the major advantage of using const over #define is that #defines don't respect scopes so there is no way to create a class scoped namespace. While const variables can be scoped in classes.
Apart from that there are other subtle advantages like:
Avoiding 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.
Ease of Debugging:
Also for same reasons mentioned in #2, while debugging #define would provide no help really.
Another reason that hasn't been mentioned yet is that const variables allow the compiler to perform explicit type-checking, but macros do not. Using const can help prevent subtle data-dependent errors that are often difficult to debug.
I think the main advantage is that you can change the constant without having to recompile everything that uses it.
Since a macro change will effectively modify the contents of the file that use the macro, recompilation is necessary.
In C the const qualifier does not define a constant but instead a read-only object:
#define A 42 // A is a constant
const int a = 42; // a is not constant
A const object cannot be used where a real constant is required, for example:
static int bla1 = A; // OK, A is a constant
static int bla2 = a; // compile error, a is not a constant
Note that this is different in C++ where the const really qualifies an object as a constant.
The only problems you list with const sum up as "I've got the most incompetent compiler I can possibly imagine". The problems with #define, however, are universal- for example, no scoping.
There's no reason to use #define instead of a const int in C++. Any decent C++ compiler will substitute the constant value from a const int in the same way it does for a #define where it is possible to do so. Both take approximately the same amount of flash when used the same way.
Using a const does allow you to take the address of the value (where a macro does not). At that point, the behavior obviously diverges from the behavior of a Macro. The const now needs a space in the program in both flash and in RAM to live so that it can have an address. But this is really what you want.
The overhead here is typically going to be an extra 8 bytes, which is tiny compared to the size of most programs. Before you get to this level of optimization, make sure you have exhausted all other options like compiler flags. Using the compiler to carefully optimize for size and not using things like templates in C++ will save you a lot more than 8 bytes.