In which scope should variables be declared?

E

elzacho

I would like to (and commonly do) define my variables in the most
specific scope I can. For example...

int foo(int a, int b, int c)
{
/* don't declare temp here if we can help it */
...

for (i = 0; i < max; i++)
{
/* declare here */
int temp;
...
/* use temp */
}
}

But my concern is, does the declaration take up cpu time? One can
imagine that temp could be a huge array or max could be a large number.
In this case, if the declaration maps to any cpu time when compiled,
this could lead to a significant performance drop.

So, is there a difference in the machine code between declaring all of
your variables at outer most scope or inner most scope? My impressions
on C are that it makes does not impose how this is handled, rather that
this is a compiler issue, but I am not sure how much the standards
dictate this. Thought I would pass it by some experts.

Zach
 
G

Gordon Burditt

I would like to (and commonly do) define my variables in the most
specific scope I can. For example...

int foo(int a, int b, int c)
{
/* don't declare temp here if we can help it */
...

for (i = 0; i < max; i++)
{
/* declare here */
int temp;
...
/* use temp */
If you expect temp to have its value survive from one interation
of this loop to the next, DON'T declare it inside the for loop.
Logically, the variable is destroyed and re-created each iteration
of the loop.
}
}

But my concern is, does the declaration take up cpu time?
Maybe.

One can
imagine that temp could be a huge array or max could be a large number.

Does adding a million take more time than adding one?
In this case, if the declaration maps to any cpu time when compiled,
this could lead to a significant performance drop.

Standard C does not guarantee that a program has performance to drop.
If you can't measure it, don't worry about it. If you haven't got
time to measure it, you don't have time to worry about whether it
takes CPU time.
So, is there a difference in the machine code between declaring all of
your variables at outer most scope or inner most scope?

Possibly. If you declare the variables at the innermost scope,
those in different blocks may overlap each other, making the offsets
different. That's a difference in the machine code. I didn't say
it was a difference in the execution time.
My impressions
on C are that it makes does not impose how this is handled, rather that
this is a compiler issue, but I am not sure how much the standards
dictate this. Thought I would pass it by some experts.

C rarely dictates HOW anything is handled. It's just supposed to work
as indicated.

Gordon L. Burditt
 
E

Eric Sosman

elzacho wrote On 09/23/05 16:17,:
I would like to (and commonly do) define my variables in the most
specific scope I can. For example...

int foo(int a, int b, int c)
{
/* don't declare temp here if we can help it */
...

for (i = 0; i < max; i++)
{
/* declare here */
int temp;
...
/* use temp */
}
}

But my concern is, does the declaration take up cpu time? One can
imagine that temp could be a huge array or max could be a large number.
In this case, if the declaration maps to any cpu time when compiled,
this could lead to a significant performance drop.

So, is there a difference in the machine code between declaring all of
your variables at outer most scope or inner most scope? My impressions
on C are that it makes does not impose how this is handled, rather that
this is a compiler issue, but I am not sure how much the standards
dictate this. Thought I would pass it by some experts.

The language Standard doesn't say much about speed or
about implementation techniques, so your question will have
different answers on different platforms. What follows is
"typical" but by no means universal:

- There is likely to be no cost for creating `temp' in
the example you've given, in the sense that the loop
will take no longer.

- There could be a space cost if you have several such
`temp' variables in different scopes. The compiler
might devote different memory cells to each `temp',
when it would have allocated just one cell to a single
`temp' at a higher level.

- ... but on the other hand there might actually be a
"negative cost" if by restricting the scope of `temp'
you make it easier for the compiler to discover that
it and `jcounter' never exist at the same time, and
so can share the same storage -- perhaps even the same
CPU register.

For ordinary scalars like your `temp' the penalties or
benefits are likely to be so small that they're difficult to
measure. But if `temp' is something more complicated the
picture may change:

- If `temp' is large, it would be wise to ensure that the
compiler allocates just one batch of memory for it. If
you have other large `temp' objects of the same type in
other disjoint inner scopes, the compiler might assign
separate memory locations to each occurrence.

- If `temp' has an initializer, the initialization will
occur on every iteration of the loop. If you don't
need that to happen, don't pay for it.

- If `temp' is a C99 variable-length array (`int temp[n]'
where `n' is variable), there may be additional costs
to allocate and deallocate memory on each iteration.

Recommendation: Simple scalars and other small objects
are good candidates for the treatment you like, especially
if they don't need initializers. Large objects, objects with
initializers, and VLAs are probably not such good candidates.

"Not necessarily. Bless you, it all depends!"
-- Pitti-Sing
 
S

SM Ryan

# for (i = 0; i < max; i++)
# {
# /* declare here */
# int temp;
# ...
# /* use temp */
# }
# }
#
# But my concern is, does the declaration take up cpu time? One can
# imagine that temp could be a huge array or max could be a large number.
# In this case, if the declaration maps to any cpu time when compiled,
# this could lead to a significant performance drop.

Depends on the compiler. However most compilers nowadays allocate all
the auto variables all at once on procedure entry and deallocate all
at once on procedure exit.

The other cost has to do with virtual memory and allocating and/or
faulting pages in the stack frame. Small changes in the frame size
are likely to have no visible effect.

# So, is there a difference in the machine code between declaring all of
# your variables at outer most scope or inner most scope? My impressions

On compiler with block level instead of procedure level addressing,
yes. But I don't know if there are C compilers that do block level
addressing.
 
E

Emmanuel Delahaye

elzacho wrote on 23/09/05 :
I would like to (and commonly do) define my variables in the most
specific scope I can. For example...

GOod and encouraged practice.
int foo(int a, int b, int c)
{
/* don't declare temp here if we can help it */
...

for (i = 0; i < max; i++)
{
/* declare here */
int temp;
...
/* use temp */
}
}

Sounds good to me.
But my concern is, does the declaration take up cpu time? One can
imagine that temp could be a huge array or max could be a large number.
In this case, if the declaration maps to any cpu time when compiled,
this could lead to a significant performance drop.

Well, it's out of the scope of the C-language. No generic answer can be
given except "it's implementation-dependent". If you are concerned by a
peculiar behaviour for a given implementation, test your code
performances on it.

Out of curiosity(?), you also can have a look to the generated assembly
code, but please, don't quick draw conclusions. Some compilers (or
compiler options) are more clever than others...

--
Emmanuel
The C-FAQ: http://www.eskimo.com/~scs/C-faq/faq.html
The C-library: http://www.dinkumware.com/refxc.html

"It's specified. But anyone who writes code like that should be
transmogrified into earthworms and fed to ducks." -- Chris Dollin CLC
 
M

Malcolm

elzacho said:
But my concern is, does the declaration take up cpu time? One can
imagine that temp could be a huge array or max could be a large number.
In this case, if the declaration maps to any cpu time when compiled,
this could lead to a significant performance drop.
In C you don't normally have to worry too much about this. (The exception is
when you have a large array that you initialise to a set value).
Normally the compiler will, at most, increment or decrement a stack
register.
In other languages it may be an issue, because objects require elaborate
contruction and destruction as they go in and out of scope.
So, is there a difference in the machine code between declaring all of
your variables at outer most scope or inner most scope? My impressions
on C are that it makes does not impose how this is handled, rather that
this is a compiler issue, but I am not sure how much the standards
dictate this. Thought I would pass it by some experts.
Your impressions are right. The details of a compiler may differ, and the
standard only require that the output be as specified. However compiler
writers are not perverse, and will try to avoid expensive operations if
possible.

Scope is really a concept for the human programmer rather than the machine.
Almost always variables shold be given the scope that makes most sense to
the human programmer. In my opinion there is a rule of three - humans can
cope with three levels of parentheses at most. So if you have global, static
file scope, and local variables, you have used up your three, and further
levels are confusing.
 

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
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top