What is the difference between #define and const? [duplicate] - c++

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.

Related

Macro can be converted to constexpr [duplicate]

In various C code, I see constants defined like this:
#define T 100
Whereas in C++ examples, it is almost always:
const int T = 100;
It is my understanding that in the first case, the preprocessor will replace every instance of T with 100. In the second example, T is actually stored in memory.
Is it considered bad programming practice to #define constants in C++?
Is it considered bad programming practice to #define constants in C++?
Yes, because all macros (which are what #defines define) are in a single namespace and they take effect everywhere. Variables, including const-qualified variables, can be encapsulated in classes and namespaces.
Macros are used in C because in C, a const-qualified variable is not actually a constant, it is just a variable that cannot be modified. A const-qualified variable cannot appear in a constant expression, so it can't be used as an array size, for example.
In C++, a const-qualified object that is initialized with a constant expression (like const int x = 5 * 2;) is a constant and can be used in a constant expression, so you can and should use them.
There is no requirement that T be stored "in memory" in the second case, unless you do something like take the address of it. This is true of all variables.
The reason the second one is better is that the first will frequently "disappear" in the pre-processor phase so that the compiler phase never sees it (and hence doesn't give it to you in debug information). But that behaviour is not mandated by the standard, rather it's common practice.
There's little need to use #define statements any more other than for conditional compilation. Single constants can be done with const, multiple related constants can be done with enum and macros can be replaced with inline functions.
Due to the differences between the concepts of constant in C and C++, in C we are basically forced to use #define (or enum) most of the time. const just doesn't work in C in most cases.
But in C++ there's no such problem, so it is indeed bad practice to rely on #defined constants in C++ (unless you really need a textually-substituted constant for some reason).
Preprocessor macros do not respect the scope - it's a simple text substitution - while static const int blah = 1; can be enclosed in a namespace. The compiler will still optimize both cases (unless you take address of that variable) but it's type- and scope-safe.
Yes. At the very least, use enums. Both const int and enums will be evaluated at compile-time, so you have the same performance. However, it's much cleaner, will be easier to debug (the debugger will actually know what T is), it's type-safe, and less likely to break in complex expressions.
Yes. The biggest reason is that preprocessor definitions do not obey the scoping rules of the language, polluting the global namespace, and worse -- they're even replaced in cases like
x->sameNameAsPreprocessorToken
Since preprocessor definitions are replaced at the textual level, other normal properties of variables do not apply - you can take the address of an int const, but not of a #define'd constant.
As noted by others, you also typically lose type safety and debugging ability.
One other cool point is that global integral constants could be optimized out by the compiler so that they do not take up any space (i.e., memory). Therefore, they can be treated as literal constants when they are used and be as optimal as #define based constants, without all of the pre-processor issues.

Memory optimization while using const vs #define in C++. Is it dependent on types? [duplicate]

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.

What is the difference between #define and creating a normal type?

In C/C++, what is the difference between using #define [and #ifndef #endif] to create values, when you can easily do it with an int or std::string [C++] too?
#ifndef MYVAL
#define MYVAL(500)
#endif
//C++
cout << MYVAL << endl;
//C
printf(MYVAL);
//C++
int MYVAL = 500;
cout << MYVAL << endl;
//C
int MYVAL = 500;
printf(MYVAL);
Your assumptions are wrong. #define doesn't create "values", it creates replacement text in your source code. It has basically nothing to do with C or C++ at all.
Before I jump into history, here's a brief understanding of the difference between the two.
Variables are, well, variables. They take up space in the compiled program, and unless you mark them with const (which is a much later development than macros), they're mutable.
Macros, on the other hand, are preprocessed. The compiler never sees the macro. Instead, the macros are handled before compiling. The precompiler goes through the code, finds every macro, and replaces it verbatim with the macro text. This can be very powerful, somewhat useful, and fairly dangerous (since it's modifying code and never does any checking when doing so).
Also, macros can be set on the command line. You can define as many things as you want when you are compiling, and if your code checks for that macro, it can behave differently.
Macros existed long before C++. They have been useful for many things:
You can use them very easily to represent constant expressions. They can save space, because they don't require any variables (though the constant expression still needs to be compiled in somewhere), and they existed before the const specifier, so they were an easy way to maintain constant "variables" - the precompiler would replace all instances of MYVAR with 500.
You can do all sorts of functions with them. I actually never made any myself, because the benefits never seemed to outweigh the risks. Macro functions that aren't carefully constructed can easily break your compile. But I have used some predefined macro functions.
#define macros are still used for many things
include guards (header files usually have a macro defined at the top, and check if it's defined to make sure they don't add it again),
TRUE and FALSE in C,
setting DEBUG mode so that code can behave differently for debugging and release. As one simple example, assertions are functions that behave differently if the DEBUG macro is present. (If it's not present, it returns completely empty code.)
In the limited case where you're simply using a macro to represent a constant expression, you're right - they're no longer needed for that.
The difference is that with the macros (#) the preprocessor does a search and replace on that symbol. There is no type checking on the replace.
When you create a variable, it is typed and the compiler will do type checking where you use it.
C/C++ compilers are often thought of as 2-pass compilers. The first pass is the preprocessor which does search and replace on macros. The second pass is the actual compilation where the declared variables are created.
Macros are often used to create more complex expressions so the code doesn't have to be repeated more than once and so the syntax is more compact. They are useful, but also more dangerous due to their 'blind' search and replace nature. In addition, you can't step into a macro with a debugger so they can be harder to troubleshoot.
Also, macros do not obey any scoping rules. #define MYVAL(500) will replace MYVAL with 500 even if it occurs in functions, global scope, class declarations, etc. so you have to be more careful in that way.
When you #define something, it will be blindly replaced whenever it's found in your code:
#define the_answer 42
/// ...
int the_answer = /* oops! */
There are few important reasons why you shouldn't use #defines. For your questions in particular I would say, #define are plain text replacements and you can't limit the scope of the macro. i.e, you can't specify an access specifier or bind it to a namespace, so once you define the macros you can use them anywhere in the files where the define is included.
With 'const' variables you can have them bound in a scope
These could help : http://www.parashift.com/c++-faq/const-vs-define.html
http://www.parashift.com/c++-faq/preprocessor-is-evil.html
There is a huge difference:
a) #define MYVAL 500
This will create a macro. Each of its occurences in the source code will be replaced by its raw value by the preprocessor. It completely ignores the scope and you cannot change its value
b) int MYVAL = 500;
This is a regular variable that obeys scope rules, i. e. when declared inside a function, it cannot be seen outside it, it can be shadowed within another function, etc...
On the other hand, variables cannot be used in preprocesor conditions (#if, #endif blocks)
One last example:
#define MYVAL 500
int main() {
int MYVAL = 10; // illegal, gets preprocessed as int 500 = 10;
}
Same with variable:
int MYVAL = 500
int main() {
int MYVAL = 10; // legal, MYVAL now references local variable, ::MYVAL is the global variable
}

Defining the complex constant "i" in C++ (#define vs const)

I'm wondering what is the "best practice" to define the complex constant "i" in C++.
I know that the "#define vs const in C++" question has been asked multiple times, and that the general answer is that it's best to use const.
However, I'm thinking that it makes sense to use #define instead of const to define mathematical constants (such as "i" or "pi"), because we don't think of them as variables, but "absolute constants" (in the accepted answer here, one can read: "A constant defined with the const qualifier is best thought of as an unmodifiable variable."). Also, I see that in the math.h library, constants are defined this way, e.g. #define M_E 2.71828182845904523536028747135266250 /* e */.
So I'm wondering, how do C++ programmers usually define the complex constant i?
Lastly, I have a small issue with my current code #define I std::complex<double>(0.0, 1.0): precompilation causes a name clash with a Qt library that I use (as soon as I enable C++11 support).
Best practise is to declare a static const instance, with either a distinctive name or in a namespace.
Your #define does not define a mathematical constant. It defines a macro which expands to std::complex<double>(0.0, 1.0). Why are they different?
1. Scope
Every time the compiler finds a token called I, whether it could be a variable name or not, will be replaced. It doesn't matter if it's a type name, a template parameter, a variable or a function argument - it will be replaced. It doesn't matter if it's in a namespace either, since the preprocessor doesn't understand them. You've already seen this break Qt, which is precisely the reason macros are generally deprecated for declaring constants.
Where they are used, it's vital to make sure the name is unique - but there's no easy way to do this.
2. Semantics
If I declare a static constant variable (ie, one that doesn't vary despite the name), it's useable just like any instance of that type - and a smart optimizer can probably avoid loading the global. However, the macro declares a new anonymous temporary each time it is referenced. There will be at least some cases where the duplicate instances can't be elided.

C/C++ - Is it Recommended to use const static or #define [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
“static const” vs “#define” in C
My first thought is that this is implied, but is there ever a reason why you would use const instead of #define?
If you set a global variable, why would you ever want to change it, and wouldn't you want to protect it globally as well?
Const usually replaces #define
#define is a pre-processor macro that can do textual replacement. You can use it to define a constant or a macro or do all sorts of other things.
const is a type-safe way to define a compile-time constant
These two mechanisms occur at different times in the compilation process, but in general, const was created to rectify the problems of #define.
I've rarely seen people do something like
#define CONSTINT const int
but it is legal.
const is only relevant for variables that are passed around at runtime that ensures that subroutines cannot change them. #define is a preprocessor compiletime directive that replaces whatever you define with what you have defined it as. Therefore, they are for different purposes.
Edit this is an answer to your original question, of whether you'd use const with a define ... it doesn't really make sense now you've edited the question to ask something different.
A #define does not define a variable, so you can't change it anyway, so the question doesn't make sense.
This isn't even possible:
#define FOO 99
int main()
{
FOO = 98;
}
Because the preprocessor substitutes the macro FOO for the replacement 99, so the compiler sees this code:
int main()
{
99 = 98;
}
And obviously that's nonsense. You can't assign to a literal, it's not a variable (const or not) it's just a value.