#define vs. const

R

Robert

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.
 
E

E. Robert Tisdale

Robert said:
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.
#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.
 
G

Greg Comeau

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.
 
J

JKop

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
 
I

Ivan Vecerina

JKop said:
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
 
I

Ioannis Vranos

JKop said:
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.
 
R

Rolf Magnus

JKop said:
Robert posted:



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.
 
C

Chris Theis

[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 {}; \
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
 
I

Ioannis Vranos

Chris said:
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?
 
C

Chris Theis

Ioannis Vranos said:
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.
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
 
I

Ioannis Vranos

Chris said:
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?
 
N

Nicolas Pavlidis

Ioannis Vranos said:
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
 
E

Eric Schmidt

Rolf Magnus said:
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.
 
I

Ioannis Vranos

Nicolas said:
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?
 
N

Nicolas Pavlidis

Ioannis Vranos said:
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
 
R

Rolf Magnus

Eric said:
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++);
 
M

Markus Elfring

#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.
 
T

Thomas Matthews

Robert said:
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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,176
Messages
2,570,947
Members
47,498
Latest member
log5Sshell/alfa5

Latest Threads

Top