f



"#define" vs "const int"

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?

0
12/30/2008 3:04:53 PM
comp.lang.c 30657 articles. 3 followers. spinoza1111 (3246) is leader. Post Follow

20 Replies
368 Views

Similar Articles

[PageSpeed] 1

Eric wrote:
> 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?
> 
lcc-win will do this. If you say

static const int foo = 4;

it will not allocate space for it. Otherwise it has to allocate space
since it could be used in some other module.

-- 
jacob navia
jacob at jacob point remcomp point fr
logiciels/informatique
http://www.cs.virginia.edu/~lcc-win32
0
jacob24 (973)
12/30/2008 3:21:17 PM
Eric <answer.to.newsgroup@nospam.com> writes:

> 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?

It would be tricky to do that if `foo' is either an object with
external linkage or an object whose address is taken.  Otherwise,
this seems fairly likely.
-- 
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
0
blp (3956)
12/30/2008 3:23:48 PM
"Eric" <answer.to.newsgroup@nospam.com> wrote in message 
news:a0ekl4dclmfborsdg4hj1igc0splk3dmem@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?
>
If you've got to worry about the space for an int then you are probably on 
such a small system that I wouldn't bank on the compiler doing any 
aggressive optimisations.

-- 
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

0
regniztar (3128)
12/30/2008 3:41:05 PM
Eric wrote:
> 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?

It's possible, but not guaranteed.  If you take the address of foo, or 
declare it in a way that gives it external linkage, the compiler cannot 
eliminate it.

And, defying common sense, a "const int" is not a "constant integer 
expression" in C, as it would be in C++, so it can't be used in some 
places (e.g. a case statement in a switch) that the #define version can. 
  However, you do get the benefit of additional type checking, so IMHO 
it's worth converting as many examples as you can.

S
0
stephen (1366)
12/30/2008 3:44:27 PM
"Malcolm McLean" <regniztar@btinternet.com> writes:
> "Eric" <answer.to.newsgroup@nospam.com> wrote in message
> news:a0ekl4dclmfborsdg4hj1igc0splk3dmem@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?
>>
> If you've got to worry about the space for an int then you are
> probably on such a small system that I wouldn't bank on the compiler
> doing any aggressive optimisations.

Such a small system would probably have a cross-compiler, not compiler
running on the system itself, so it would be free to do all the
agressive optimization it likes.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
kst-u (21963)
12/30/2008 3:48:01 PM
jacob navia <jacob@nospam.org> writes:

> Eric wrote:
>> 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?
>>
> lcc-win will do this. If you say
>
> static const int foo = 4;
>
> it will not allocate space for it. Otherwise it has to allocate space
> since it could be used in some other module.

How does it do this, if the address of foo is taken?
-- 
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}
0
blp (3956)
12/30/2008 4:32:12 PM
"Keith Thompson" <kst-u@mib.org> wrote in message 
news:lnabad3bri.fsf@nuthaus.mib.org...
> "Malcolm McLean" <regniztar@btinternet.com> writes:
>> "Eric" <answer.to.newsgroup@nospam.com> wrote in message
>> news:a0ekl4dclmfborsdg4hj1igc0splk3dmem@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?
>>>
>> If you've got to worry about the space for an int then you are
>> probably on such a small system that I wouldn't bank on the compiler
>> doing any aggressive optimisations.
>
> Such a small system would probably have a cross-compiler, not compiler
> running on the system itself, so it would be free to do all the
> agressive optimization it likes.
>
But there's likely only a small market for it. And embedded programmers 
often like to see a one to one mapping between C source and assembly.

-- 
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

0
regniztar (3128)
12/30/2008 5:01:51 PM
Malcolm McLean wrote:
> 
> "Keith Thompson" <kst-u@mib.org> wrote in message 
> news:lnabad3bri.fsf@nuthaus.mib.org...
>> "Malcolm McLean" <regniztar@btinternet.com> writes:
>>> "Eric" <answer.to.newsgroup@nospam.com> wrote in message
>>> news:a0ekl4dclmfborsdg4hj1igc0splk3dmem@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?
>>>>
>>> If you've got to worry about the space for an int then you are
>>> probably on such a small system that I wouldn't bank on the compiler
>>> doing any aggressive optimisations.
>>
>> Such a small system would probably have a cross-compiler, not compiler
>> running on the system itself, so it would be free to do all the
>> agressive optimization it likes.
>>
> But there's likely only a small market for it.

Or a large market if it is one of the popular embedded processors.

> And embedded programmers 
> often like to see a one to one mapping between C source and assembly.

All the ones I've met wanted to see the fastest possible code produced 
from their C sources, with the sole exception of where they used volatile.
-- 
Flash Gordon
0
spam331 (4048)
12/30/2008 6:13:02 PM
On Tue, 30 Dec 2008 17:01:51 -0000, "Malcolm McLean"
<regniztar@btinternet.com> wrote:

>
>"Keith Thompson" <kst-u@mib.org> wrote in message 
>news:lnabad3bri.fsf@nuthaus.mib.org...
>
>> Such a small system would probably have a cross-compiler, not compiler
>> running on the system itself, so it would be free to do all the
>> agressive optimization it likes.
>>
>But there's likely only a small market for it. And embedded programmers 
>often like to see a one to one mapping between C source and assembly.

Good afternoon, Malcolm and Keith.

Yes, this is a small system with limited memory.  The compiler in use
is the IAR, which claims VERY aggressive optimization.  Those who want
to see a one to one mapping between C and assembly can turn
optimization off.  In fact, it's reported that sometimes the
optimization has to be turned off to get the debugger to work
correctly.

0
12/30/2008 6:41:10 PM
Stephen Sprunk wrote:
> Eric wrote:
> > 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?
> 
> It's possible, but not guaranteed.  If you take the address of foo, or 
> declare it in a way that gives it external linkage, the compiler cannot 
> eliminate it.

If it's local, the optimizer can still eliminate it:

    const int foo = 4;
    const int* p = &foo;
    printf( "%d\n", *p );

The last line is probably optimized to printf( "%d\n", 4 ). With modern 
optimizers, foo doesn't even need to be const, since the optimizer can 
see whether it's modified.

> And, defying common sense, a "const int" is not a "constant integer 
> expression" in C, as it would be in C++, so it can't be used in some
                          ^^^^^^^^
Could be, since it might be dynamically initialized (const int i = f(); 
for example) and thus not known at compile-time.

> places (e.g. a case statement in a switch) that the #define version can. 
> However, you do get the benefit of additional type checking, so IMHO 
> it's worth converting as many examples as you can.

One common alternative to #define for int is enum. It's scoped and 
doesn't require parenthesizing the entire expression. On the downside, 
it's a distinct type, which might cause compiler warnings.

    enum { foo = 4 };
0
blargg.h4g (301)
12/30/2008 8:31:51 PM
blargg <blargg.h4g@gishpuppy.com> writes:
[...]
> One common alternative to #define for int is enum. It's scoped and 
> doesn't require parenthesizing the entire expression. On the downside, 
> it's a distinct type, which might cause compiler warnings.
>
>     enum { foo = 4 };

The enum declaration creates a distinct type, but the literals are of
type int.  So, for example, given:

    enum e { foo = 4 };
    enum e obj;

obj is of type "enum e", but foo is of type int.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
kst-u (21963)
12/30/2008 8:45:51 PM
Eric wrote:
> 
> 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?

I would expect that any such optimization would not be legal in C. 
C++ is another matter, and I don't know the answer.

-- 
Merry Christmas, Happy Hanukah, Happy New Year
 Joyeux Noel, Bonne Annee, Frohe Weihnachten
Chuck F (cbfalconer at maineline dot net)
     <http://cbfalconer.home.att.net>
0
cbfalconer (19194)
12/30/2008 9:42:01 PM
CBFalconer <cbfalconer@yahoo.com> writes:

> Eric wrote:
>> 
>> 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?
>
> I would expect that any such optimization would not be legal in C. 

Why?

-- 
Ben.
0
ben.usenet (6790)
12/30/2008 9:50:15 PM
Eric wrote:
> 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?

If you declare

	const int foo = 4;

At block scope, and only use it in ways that would be legal with either 
method, than a sufficiently good optimizing compiler will probably 
generate essentially the same code with either approach.

However if you declare it at file scope, it will have external linkage. 
The compiler must therefore set aside actual memory for 'foo', just in 
case some other module in the same program contains code like the following:

	extern const int foo;

	const int *pi = &foo;

It would require pretty tight coupling between a compiler and a linker 
to determine that there is no such module, and as a result remove the 
object.
0
jameskuyper (5635)
12/30/2008 9:52:37 PM
James Kuyper wrote:
> Eric wrote:
>> 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?
> 
> If you declare
> 
>     const int foo = 4;
> 
> At block scope, and only use it in ways that would be legal with either 
> method, than a sufficiently good optimizing compiler will probably 
> generate essentially the same code with either approach.

True.

> However if you declare it at file scope, it will have external linkage. 

Usage within the same file is still likely to be optimed away.

> The compiler must therefore set aside actual memory for 'foo', just in 
> case some other module in the same program contains code like the 
> following:
> 
>     extern const int foo;
> 
>     const int *pi = &foo;
> 
> It would require pretty tight coupling between a compiler and a linker 
> to determine that there is no such module, and as a result remove the 
> object.

It does not really require tight coupling between the compiler and 
linker. The compiler can flag foo as defined but not used in the first 
module, then the linker just has to remember if any other module refer 
to it (and it needs to detect the references anyway to resolve them) and 
eliminate it if it is not used. I don't know if any linkers actually do 
this though.
-- 
Flash Gordon
0
spam331 (4048)
12/30/2008 10:09:39 PM
>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?

There are no guarantees, as the compiler might consider leaving the
variable in as being faster or smaller code.  If the address of foo
is taken, this makes it harder to do that optimization (if it is
an optimization), especially if the address is passed outside the
function.

What do you mean by "allocate memory for the int"?  Does the constant
4 used as part of a machine instruction count?  It's quite possible
that if you have the statement 
	bar = foo;
where bar is an auto int, it will be compiled into a machine
instruction "move immediate to a stack-frame-relative memory
location", so there's no specific memory location for foo.  Eliminating
what might be 4 bytes for an int variable might end up costing more
than 4 bytes in code size, with the gain of faster execution.

0
12/30/2008 11:40:46 PM
CBFalconer said:

> Eric wrote:
>> 
>> 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?
> 
> I would expect that any such optimization would not be legal in C.

It's perfectly legal provided that a strictly conforming program 
can't tell the difference. Let us assume that there is a way to 
construct such a program. We then have three classes of programs:

(a) strictly conforming programs that can tell the difference;
(b) strictly conforming programs that can't tell the difference 
(because they don't try);
(c) conforming programs that are not strictly conforming.

The optimisation technique is legal for classes (b) and (c), but not 
for class (a).

<snip>

-- 
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
0
rjh (10790)
12/31/2008 12:28:00 AM
Ben Bacarisse wrote:
> CBFalconer <cbfalconer@yahoo.com> writes:
>> Eric wrote:
>>>
>>> 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?
>>
>> I would expect that any such optimization would not be legal in C.
> 
> Why?

For example, there are ways of beating the 'const'
characterization, via pointers etc.  They may be in other modules,
and thus totally undetectable.  If this is not sufficient, or not
sufficiently illegal, there is also the problem of preventing it
and avoiding taking the address (which would not exist).

-- 
Merry Christmas, Happy Hanukah, Happy New Year
 Joyeux Noel, Bonne Annee, Frohe Weihnachten
Chuck F (cbfalconer at maineline dot net)
     <http://cbfalconer.home.att.net>
0
cbfalconer (19194)
12/31/2008 1:10:01 AM
CBFalconer <cbfalconer@yahoo.com> writes:
> Ben Bacarisse wrote:
>> CBFalconer <cbfalconer@yahoo.com> writes:
>>> Eric wrote:
>>>>
>>>> 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?
>>>
>>> I would expect that any such optimization would not be legal in C.
>> 
>> Why?
>
> For example, there are ways of beating the 'const'
> characterization, via pointers etc.  They may be in other modules,
> and thus totally undetectable.

Anything that avoids the "const" qualification invokes undefined
behavior, and this is irrelevant to the question of whether the
optimization is legal.

>                                 If this is not sufficient, or not
> sufficiently illegal, there is also the problem of preventing it
> and avoiding taking the address (which would not exist).

Right, if the address is taken (and the code that takes the address
can't be optimized away), then space has to be allocated.  But if the
compiler (or linker) can prove that the address is never taken, or if
any code that depends on the address can be optimized away, then the
object itself can be optimized away.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
kst-u (21963)
12/31/2008 1:41:06 AM
CBFalconer wrote:
> Ben Bacarisse wrote:
>> CBFalconer <cbfalconer@yahoo.com> writes:
>>> Eric wrote:
>>>> 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?
>>> I would expect that any such optimization would not be legal in C.
>> Why?
> 
> For example, there are ways of beating the 'const'
> characterization, via pointers etc.  They may be in other modules,
> and thus totally undetectable. ...

Any such methods have undefined behavior; one permissible form for that 
undefined behavior is for the use of those methods to fail to have any 
effect on code making use of foo.

> ... If this is not sufficient, or not
> sufficiently illegal, there is also the problem of preventing it
> and avoiding taking the address (which would not exist).

He was talking about

	const int foo = 4;

as a replacement for

	#define foo 4

Code with defined behavior which uses the macro can't involve taking the 
address of foo, so the issue never comes up.

0
jameskuyper (5635)
12/31/2008 2:02:19 AM
Reply: