Style of Local Variable Declaration

  • Thread starter Michael B Allen
  • Start date
M

Michael B Allen

Which style of local variable declaration do you prefer; put everything
at the top of a function or only within the block in which it is used?

For example;

void
fn(struct foo *f, int bar)
{
struct abc d;
int i;

abc_init(&d);

for (i = 0; i < bar; i++) {
unsigned long num;
struct eee *e;

for (e = f->a; e < f->alim; e++) {
time_t time time_now;
struct tm tm_now;
struct blah b;
...

OR

void
fn(struct foo *f, int bar)
{
struct abc d;
int i;
unsigned long num;
struct eee *e;
time_t time time_now;
struct tm tm_now;
struct blah b;

abc_init(&d);

for (i = 0; i < bar; i++) {
for (e = f->a; e < f->alim; e++) {
...

I've tended to use the second form based on the belief that frequent
movement of the stack pointer would lead to inefficiencies but I have no
idea if my instinct is true.

Mike
 
B

Bruno Desthuilliers

Michael said:
Which style of local variable declaration do you prefer; put everything
at the top of a function or only within the block in which it is used?
(snip code exemples)

The first one, definitively.
"Thou shall limit variables visibility to the most possible restricted
block"
...

I've tended to use the second form based on the belief that frequent
movement of the stack pointer would lead to inefficiencies but I have no
idea if my instinct is true.

I'm not sure, but I guess this will greatly differ according to the
implementation and the optimization options. But I would not even care
about this anyway. I prefer to write clear, readable and if possible
robust code.

Bruno
 
K

Kevin Bracey

In message <[email protected]>
Michael B Allen said:
Which style of local variable declaration do you prefer; put everything
at the top of a function or only within the block in which it is used?

I've tended to use the second form based on the belief that frequent
movement of the stack pointer would lead to inefficiencies but I have no
idea if my instinct is true.

It works both ways. By limiting the lifetime of variables you're potentially
reducing stack and register usage whereever the lifetimes don't overlap.
But yes, in some implementations, the stack pointer might move up and down as
you move in and out of blocks. But stack pointer moves are probably cheap,
and if they weren't the implementation probably wouldn't do it.

And a smart compiler may well be able to figure out which variables are
disjoint and allow them to share registers/memory (live range splitting),
regardless of how you declare them.

I really wouldn't worry about efficiency too much - just worry about the
C code style. If I was worrying, I would tend to go with limited-scope
declarations, not function-scope ones.
 
J

j

Michael B Allen said:
Which style of local variable declaration do you prefer; put everything
at the top of a function or only within the block in which it is used?

If the variable's purpose fits logically within a specific block,
then I would declare it there.
For example;

void
fn(struct foo *f, int bar)
{
struct abc d;
int i;

abc_init(&d);

for (i = 0; i < bar; i++) {
unsigned long num;
struct eee *e;

for (e = f->a; e < f->alim; e++) {
time_t time time_now;
struct tm tm_now;
struct blah b;
...

OR

void
fn(struct foo *f, int bar)
{
struct abc d;
int i;
unsigned long num;
struct eee *e;
time_t time time_now;
struct tm tm_now;
struct blah b;

abc_init(&d);

for (i = 0; i < bar; i++) {
for (e = f->a; e < f->alim; e++) {
...

I've tended to use the second form based on the belief that frequent
movement of the stack pointer would lead to inefficiencies but I have no
idea if my instinct is true.

Why would it imply that?
 
J

John Bode

Michael B Allen said:
Which style of local variable declaration do you prefer; put everything
at the top of a function or only within the block in which it is used?

I try to limit the scope of variables as much as possible. If a
variable is only used within a certain block, it should be declared
within that block.

[snip example]
I've tended to use the second form based on the belief that frequent
movement of the stack pointer would lead to inefficiencies but I have no
idea if my instinct is true.

Mike

It probably isn't. The best way to be sure is to look at the machine
code generated by your compiler. For example, I womped up a
quick-n-dirty file that had one int at function scope, and one
declared within a for loop. The machine code showed that space had
been allocated on the stack for both at function entry; the outer
scope variable was referenced by -$4(%ebp) and the inner scope
variable by -$8(%ebp). The stack pointer doesn't change.
 
D

Dan Pop

In said:
(snip code exemples)

The first one, definitively.
"Thou shall limit variables visibility to the most possible restricted
block"

Aren't you contradicting yourself? ;-)

Dan
 
D

Dan Pop

In said:
Which style of local variable declaration do you prefer; put everything
at the top of a function or only within the block in which it is used?

A combination of the two. Declare one letter "temporaries" that are used
all over the place at the top and the other variables only in the blocks
using them.

I.e. use

void foo(void)
{
int i;
volatile extern int cond1, cond2;

while (cond1) {
double b1var;
/* code using i and b1var */
}
while (cond2) {
unsigned b2var;
/* code using i and b2var */
}
}

rather than

void foo(void)
{
volatile extern int cond1, cond2;

while (cond1) {
int i;
double b1var;
/* code using i and b1var */
}
while (cond2) {
int i;
unsigned b2var;
/* code using i and b2var */
}
}

The as-if rule allows the compiler to allocate *all* the locals used in
a function upon function entry and to destroy them upon function return.
No correct program can tell the difference.

Dan
 
A

Alan Balmer

I've tended to use the second form based on the belief that frequent
movement of the stack pointer would lead to inefficiencies but I have no
idea if my instinct is true.

Particular implementations are off-topic here, and you'll get more
accurate answers in a group discussing your implementation.

However, in most implementations and applications, I think you'll find
that time spent in stack pointer movement is unmeasurable. Limiting
the scope will give the compiler more optimization clues. In general,
trying to out-guess a modern optimizing compiler is a losing
proposition :)
 
E

Ed Morton

Which style of local variable declaration do you prefer; put everything
at the top of a function or only within the block in which it is used?
<snip>

You've already received good advice, but one other thing to (unfortunately)
consider is how your favorite debugger handles scoped variables. I've had the
misfortune of coming across one that couldn't tell which block a given variable
was in if 2 scopes held variables of the same name. For example, if you have:

1: void foo() {
2: if (tuesday) {
3: int val = 3;
4: printf("%d\n",val);
5: } else {
6: int val = 6;
7: printf("%d\n",val);
8: }
9: }

then the printf() at line 7 would print "6" but dumping the value of "val" from
the debugger at line 7 would print "3".

Ed.
 
C

CBFalconer

John said:
Michael B Allen said:
Which style of local variable declaration do you prefer; put
everything at the top of a function or only within the block
in which it is used?

I try to limit the scope of variables as much as possible. If
a variable is only used within a certain block, it should be
declared within that block.

[snip example]

I tend to declare everything at the top of a function. It the
urge to further block localize variables strikes I consider it an
indication the function is overly complex, and should be broken
into smaller functions with their own variables.

This is ONLY a tendency, and the whole thing smells of style
wars. However I consider the overly complex signal valuable.
This also appears when there are too many local variables.
 

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

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top