By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,141 Members | 1,225 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,141 IT Pros & Developers. It's quick & easy.

#define vs. const

P: n/a
Greetings everyone,

I was wondering if a const variable or object took up space. I know
that a #define'd macro doesn't, as it's basically just interpreted by
the compiler. If a const does take up space, is there any reason to
choose it over a #define'd constant?

-- Thank you

P.S. if it makes any difference, I ssh to a SunOs machine where I use
g++ as my compiler.
Jul 22 '05 #1
Share this Question
Share on Google+
19 Replies


P: n/a
In article <Xn********************@216.77.188.18>,
Robert <gr*****@REMOVEhotmail.com> wrote:
I was wondering if a const variable or object took up space.
It might, or it might not. Generally speaking, usually a scalar
integeral need not take up space if their address is not taken.
Hence, the classic situation of somehting such as:

const int buf = 99;

char a[buf];

int main()
{
return 0;
}

Here, buf can be used to obtain the constant expression necessary
for the array dimension, and at the same time, the compiler probably
won't both to allocate any runtime space for it since it isn't
otherwise used. It can get slippery though. And there are
cases where compilers normally wouldn't do it:

const double d = 1234.4321;
const int array[999]; // int, but probably still allocated.

Of course, all this is notwithstanding program optimizations
that are allowed to occur.
I know
that a #define'd macro doesn't, as it's basically just interpreted by
the compiler. If a const does take up space, is there any reason to
choose it over a #define'd constant?


Check out http://www.comeaucomputing.com/techtalk/#definevsconst
for a higher level response, and not intended to be narrowminded
since as usual decisions should be context driven.
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?
Jul 22 '05 #2

P: n/a
Robert wrote:
I was wondering if a const variable or object took up space.
You are probably confusing C with C++.
I know that a #define'd macro doesn't
as it's basically just interpreted by the compiler.
I don't think that you *know* any such thing.
cat f.cc #ifdef UH
#define constant 1024*1024
#else //UH
const int constant = 1024*1024;
#endif//UH

extern
void g(int);

void f(void) {
g(constant);
}
g++ -DUH -Wall -ansi -pedantic -O3 -S -o f.sold f.cc
g++ -Wall -ansi -pedantic -O3 -S -o f.snew f.cc
diff f.sold f.snew
My compiler emits *exactly* the same code
whether I use #define or const.
If a const does take up space,
is there any reason to choose it over a #define'd constant?


C preprocessor macro definitions are dangerous.
They don't respect local scope for example.
Jul 22 '05 #3

P: n/a
Robert posted:
Greetings everyone,

I was wondering if a const variable or object took up space. I know that a #define'd macro doesn't, as it's basically just interpreted by the compiler. If a const does take up space, is there any reason to choose it over a #define'd constant?

-- Thank you
P.S. if it makes any difference, I ssh to a SunOs machine where I use g++ as my compiler.

MACROS ARE EVIL

Don't use macros.

There's is absolutlely no need for them in C++.

Macro constants -> const global variables
Macro functions -> inline functions

If you use macros for any other reason, eg. to get some new
special syntax, then it's perverted.

Not only do macro "functions" not follow scoping rules, but
also when they're passed the likes of:

Func(++a, b+=6)

Then they may increment "a" more than once and add 6 to
"b" more than once too.

Also if you want a callback function out of a macro:

CallBack(Func)

Well, let's just say it doesn't work.

MACROS WILL DIE

-JKop
Jul 22 '05 #4

P: n/a
"JKop" <NU**@NULL.NULL> wrote in message
news:pK******************@news.indigo.ie...
MACROS ARE EVIL

Don't use macros.

There's is absolutlely no need for them in C++.

Macro constants -> const global variables
Macro functions -> inline functions
I agree that macros are evil, and that in most of their
current uses, they are best replaced as you suggested.
However, I wouldn't go as far as to say that there are
absolutely no need for them.
Include guards are usually based on macros, right?
If you use macros for any other reason, eg. to get some new
special syntax, then it's perverted. .... MACROS WILL DIE


Someday they may well be replaced by a better/safer mechanism.
So far, many find that there are still many legitimate uses
for them, and even developed supporting libraries.
For advanced examples see:
http://www.boost.org/libs/preprocessor/doc/index.html

At the language level itself, I wouldn't bet that new
extensions to the C preprocessor (e.g. variadic arguments)
won't be adopted in the next C++ standard.
Regards,
Ivan
--
http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form

Jul 22 '05 #5

P: n/a
JKop wrote:
MACROS ARE EVIL

Don't use macros.

There's is absolutlely no need for them in C++.
Actually there are some uses with no other alternatives like #ifndef's.
But in general, they should be avoided.

Macro constants -> const global variables
Macro functions -> inline functions


and templates.

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #6

P: n/a
JKop wrote:
Robert posted:
Greetings everyone,

I was wondering if a const variable or object took up space. I know
that a #define'd macro doesn't, as it's basically just

interpreted by
the compiler. If a const does take up space, is there any

reason to
choose it over a #define'd constant?

--

Thank you

P.S. if it makes any difference, I ssh to a SunOs machine

where I use
g++ as my compiler.

MACROS ARE EVIL

Don't use macros.


That won't help without giving a reason.
There's is absolutlely no need for them in C++.

Macro constants -> const global variables
#ifndef FOO_H_INCLUDED
#define FOO_H_INCLUDED

//foo.h contents

#endif
Macro functions -> inline functions
#define ASSERT(x) \
if (!(x)) \
std::cerr << "Assert failure in line " << __LINE__ << std::endl;
If you use macros for any other reason, eg. to get some new
special syntax, then it's perverted.
That's your opinion.
Not only do macro "functions" not follow scoping rules, but
also when they're passed the likes of:

Func(++a, b+=6)

Then they may increment "a" more than once and add 6 to
"b" more than once too.
Even further, that may introduce undefined behaviour, like in the infamous
example:

#define MIN(x, y) ((x) < (y) ? (x) : (y))

//...
int a = 3;
int b = 5;
int c = MIN(a++, b--);
Also if you want a callback function out of a macro:

CallBack(Func)

Well, let's just say it doesn't work.


Macros also don't support namespaces and cannot be made members of classes.
Further, they are not type safe.

Jul 22 '05 #7

P: n/a

"JKop" <NU**@NULL.NULL> wrote in message
news:pK******************@news.indigo.ie...
[SNIP]

MACROS ARE EVIL

Don't use macros.

There's is absolutlely no need for them in C++.
Sit back and relax for a moment ;-) I totally agree that macros are evil but
the statement that there is absolutely no need for them in C++ is more than
arguable. There are a couple of situations that spring to my mind where they
come in very handy. Just think of include guards, or of some more nifty uses
like in compile time asserts with more informative error messages. I simply
donŽt know how youŽd achieve it without a macro.

template <bool x> struct StaticAssert {
StaticAssert(...);
};
template <> struct StaticAssert<false>{};
#define COMPILE_ASSERT( Expr, Msg ) \
{ \
class ERROR_##Msg {}; \
(void)sizeof( StaticAssert<(Expr) != 0>(( ERROR_##Msg()))); \
}

Macro constants -> const global variables
Macro functions -> inline functions
Point taken and youŽre absolutey right there.

If you use macros for any other reason, eg. to get some new
special syntax, then it's perverted.
[SNIP]
MACROS WILL DIE


Wait and see, probably they might be replaced by some safer mechanism.

Regards
Chris
Jul 22 '05 #8

P: n/a
Chris Theis wrote:
Sit back and relax for a moment ;-) I totally agree that macros are evil but
the statement that there is absolutely no need for them in C++ is more than
arguable. There are a couple of situations that spring to my mind where they
come in very handy. Just think of include guards,
In most compilers inclusion guards can be replaced with #pragma
directives. Like

#pragma once
or of some more nifty uses
like in compile time asserts with more informative error messages. I simply
donŽt know how youŽd achieve it without a macro.

template <bool x> struct StaticAssert {
StaticAssert(...);
};
template <> struct StaticAssert<false>{};
#define COMPILE_ASSERT( Expr, Msg ) \
{ \
class ERROR_##Msg {}; \
(void)sizeof( StaticAssert<(Expr) != 0>(( ERROR_##Msg()))); \
}

With an array of pointers to functions or objects may be?

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #9

P: n/a
Thanks everyone for your replies. I've been searching around and saw
this article: http://www.embedded.com/story/OEG20011016S0116 . It
mentions something about const variables/objects receiving performance
penalties.

Jul 22 '05 #10

P: n/a

"Ioannis Vranos" <iv*@guesswh.at.grad.com> schrieb im Newsbeitrag
news:ci***********@ulysses.noc.ntua.gr...
Chris Theis wrote: [SNIP]
In most compilers inclusion guards can be replaced with #pragma
directives. Like

#pragma once

Yes, that's true but still compiler dependent.

or of some more nifty uses
like in compile time asserts with more informative error messages. I simply donŽt know how youŽd achieve it without a macro.

template <bool x> struct StaticAssert {
StaticAssert(...);
};
template <> struct StaticAssert<false>{};
#define COMPILE_ASSERT( Expr, Msg ) \
{ \
class ERROR_##Msg {}; \
(void)sizeof( StaticAssert<(Expr) != 0>(( ERROR_##Msg()))); \
}

With an array of pointers to functions or objects may be?


Hmm, could you please elaborate on that. I don't quite see how to gain
informative error messages from compile-time (!) asserts with pointers to
functions or objects. I'd be really interested how to do this, so I'd
appreciate an example.

Best regards
Chris

Jul 22 '05 #11

P: n/a
Chris Theis wrote:
Hmm, could you please elaborate on that. I don't quite see how to gain
informative error messages from compile-time (!) asserts with pointers to
functions or objects. I'd be really interested how to do this, so I'd
appreciate an example.

Perhaps I miss something. The actual checks aren't performed at compile
time, but at run-time, right?

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #12

P: n/a
Ioannis Vranos <iv*@guesswh.at.grad.com> writes:
Chris Theis wrote:
Hmm, could you please elaborate on that. I don't quite see how to gain
informative error messages from compile-time (!) asserts with pointers to
functions or objects. I'd be really interested how to do this, so I'd
appreciate an example.

Perhaps I miss something. The actual checks aren't performed at
compile time, but at run-time, right?


You mean the assert - macro defined in cassert, what Chris means is
something like boost::STATIC_ASSERT, which makes the ckeck at
compiletime.

Best regards,
Nicolas
--
| Nicolas Pavlidis | Elvis Presly: |\ |__ |
| Student of SE & KM | "Into the goto" | \|__| |
| pa****@sbox.tugraz.at | ICQ #320057056 | |
|-------------------University of Technology, Graz----------------|
Jul 22 '05 #13

P: n/a
Rolf Magnus <ra******@t-online.de> wrote in message news:<ci*************@news.t-online.com>...
Even further, that may introduce undefined behaviour, like in the infamous
example:

#define MIN(x, y) ((x) < (y) ? (x) : (y))

//...
int a = 3;
int b = 5;
int c = MIN(a++, b--);


There is no undefined behavior in this fragment.

--
Eric Schmidt
Jul 22 '05 #14

P: n/a
Nicolas Pavlidis wrote:
You mean the assert - macro defined in cassert, what Chris means is
something like boost::STATIC_ASSERT, which makes the ckeck at
compiletime.

How could this be possible for non compile-time constants?

--
Ioannis Vranos

http://www23.brinkster.com/noicys
Jul 22 '05 #15

P: n/a
Ioannis Vranos <iv*@guesswh.at.grad.com> writes:
Nicolas Pavlidis wrote:
You mean the assert - macro defined in cassert, what Chris means is
something like boost::STATIC_ASSERT, which makes the ckeck at
compiletime.

How could this be possible for non compile-time constants?


It's thought to be used only for things that are clear at compiletime.
For example if you're writing templates and becaus of the semantics you
have to reduce the possible types which can be passed to this template,
or if ranges were passed to a template via constants and there is a
upper and lower bound for this constants.

Best regrads,
Nicolas
--
| Nicolas Pavlidis | Elvis Presly: |\ |__ |
| Student of SE & KM | "Into the goto" | \|__| |
| pa****@sbox.tugraz.at | ICQ #320057056 | |
|-------------------University of Technology, Graz----------------|
Jul 22 '05 #16

P: n/a
Ioannis Vranos wrote:
Nicolas Pavlidis wrote:
You mean the assert - macro defined in cassert, what Chris means is
something like boost::STATIC_ASSERT, which makes the ckeck at
compiletime.

How could this be possible for non compile-time constants?


Not.

Jul 22 '05 #17

P: n/a
Eric Schmidt wrote:
Rolf Magnus <ra******@t-online.de> wrote in message
news:<ci*************@news.t-online.com>...
Even further, that may introduce undefined behaviour, like in the
infamous example:

#define MIN(x, y) ((x) < (y) ? (x) : (y))

//...
int a = 3;
int b = 5;
int c = MIN(a++, b--);


There is no undefined behavior in this fragment.


Hmm. I guess you're right. Let's just use the SQUARE example then:

#define SQUARE(x) ((x)*(x))

//...
int x = 3;
SQUARE(x++);

Jul 22 '05 #18

P: n/a
> > #define MIN(x, y) ((x) < (y) ? (x) : (y))
[...]
int c = MIN(a++, b--);


There is no undefined behavior in this fragment.


The fragment might show "unexpected" behavior. Each increment and
decrement expression can be evaluated up to twice.
Jul 22 '05 #19

P: n/a
Robert wrote:
Greetings everyone,

I was wondering if a const variable or object took up space. I know
that a #define'd macro doesn't, as it's basically just interpreted by
the compiler. If a const does take up space, is there any reason to
choose it over a #define'd constant?

-- Thank you

P.S. if it makes any difference, I ssh to a SunOs machine where I use
g++ as my compiler.


In the case where the const object is used in an expression,
it may take up space:
#include <iostream>
#include <cstdlib>

const unsigned int five = 5;

int main(void)
{
std::cout << five << std::endl;
return EXIT_SUCCESS;
}

However, it may not take up any space in this example:

unsigned char array[five];

The best method to find out what is being placed in your code is to
generate an assembly listing using the compiler or on the executable
using a debugger.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.comeaucomputing.com/learn/faq/
Other sites:
http://www.josuttis.com -- C++ STL Library book

Jul 22 '05 #20

This discussion thread is closed

Replies have been disabled for this discussion.