Re: "#define" vs "const int"
In article <cacdfefd-fe84-4e98-855d-38b4342c38e8@y1g2000pra.googlegroups.com>,
C?dric Baudry <mr.cedric.baudry@gmail.com> wrote:
On 31 d?c 2008, 14:18, ytrem...@nyx.nyx.net (Yannick Tremblay) wrote:
In article <gje3hn0...@news2.newsguy.com>,
Bill <Bill_NOS...@comcast.net> wrote:
"Eric" <answer.to.newsgr...@nospam.com> wrote in message
news:k3ekl4t4hlh4odpm2d7cfsrmfi1b3s3qhi@4ax.com...
I'm told that with most optimizing compilers, if you say "const int
foo = 4" rather than "#define foo 4", the compiler won't actually
allocate any memory for the int. True?
No one mentioned (I think) that #define is a "pre-processor directive".
The substitution of "4" for "foo" is made before the "real compilation" even
starts. Hence, no bytes for foo!
Hmm, technically correct about "foo" itself. However, the amount of memory
used by the program might be higher with the #define depending on how
it is later used. E.g. (already hinted by James)
#include <vector>
int const foo = 4;
#define FOO 4
void bar()
{
std::vector<int> v;
v.push_back(foo);
v.push_back(FOO); //will translate to v.push_back(int(FOO));
v.push_back(foo);
v.push_back(FOO); //a second temporary will be allocated
}
This is even worse:
#include <string>
#include <vector>
std::string const foo = "this a a constant string";
#define FOO "this is a macro string"
void bar()
{
std::vector<std::string> v;
v.push_back(foo);
v.push_back(FOO); //i.e. v.push_back(std::string(FOO));
v.push_back(foo);
v.push_back(FOO); //a second temporary will be allocated
}
Yan
Ok, so the define can cause infinitely more memory consuption than 0.
You seem to say that "this a a constant string" doesn't suffer the
same problem. Is it true for VC++2008 ?
For multiple usage inside a single translation unit, "std::string const
foo" will be allocated once and passed to the vector as a const
reference. For FOO, a temporary std::string will be created for each
instance.
Test it on your compiler:
#include <string>
#include <iostream>
std::string const foo = "This is a constant string";
#define FOO "This is a macro string"
void bar(std::string const & in)
{
std::cout << in << " is at: ";
std::cout << &in << std::endl;
}
int main()
{
bar(foo);
bar(FOO);
bar(foo);
bar(FOO);
return 0;
}
This gives me:
This is a constant string is at: 0x8049f38
This is a macro string is at: 0xbf9bf000
This is a constant string is at: 0x8049f38
This is a macro string is at: 0xbf9bf008
Admitedly, this is a special example constructed to highlight that
"#define do not use memory and should be used for optimisation" is
incorrect. One could write an example showing the reverse but this
would only be relevant if someone was saying that you should always
use constants because they use less memory. I don't think anyone is
sayng that.
Reasons to use const are best summarised here:
http://www.parashift.com/c++-faq-lite/newbie.html#faq-29.7
What about the const. Does it cause exacly the same problem here or in
similar cases ?
There are cases where the const will use more memory, there are cases
where the #define will be worse.
My point is that it is not true that #define use less memory. The
correct answer is (unfortunately) it depends. So anyone still using
#define for constants in C++ under the pretext that they use less
memory is lying to themselves and should learn a bit more about what
happens under the hood before trying to micro-optimise. Attempting to
reduce memory usage by using #define instead of const is IMO premature
optimisation. It is far complex than that. Attempting to
micro-optimise without understanding what you are doing is also very
dangerous. Unless you really undertand what happens, just use the
recommended techniques and accepted idioms and leave optimisation for
when and where it is needed.
Also although the #define itself is not allocated in free space /
heap, the macro gets replaced inside the code and must exist somewhere
possibly in the text/code part of the executable. This is not free
either.