Declaration of variables

G

Gaijinco

I have always felt that you should only declared variables as needed,
and implicitily it seems many authors to encourage it, but the other
day a friend told me that declaring variables inside a loop wasn't good
practice, something like:

for(int i=0; i<size-1; ++i){
int aux = array;
array=array[i+1];
array[i+1]=aux;
}

should be written like:

int aux;
for(int i=0; i<size-1; ++i){
aux = array;
array=array[i+1];
array[i+1]=aux;
}

What do you think? Thaks!
 
V

Victor Bazarov

Gaijinco said:
I have always felt that you should only declared variables as needed,
and implicitily it seems many authors to encourage it, but the other
day a friend told me that declaring variables inside a loop wasn't good
practice, something like:

for(int i=0; i<size-1; ++i){
int aux = array;
array=array[i+1];
array[i+1]=aux;
}

should be written like:

int aux;
for(int i=0; i<size-1; ++i){
aux = array;
array=array[i+1];
array[i+1]=aux;
}

What do you think? Thaks!


I think it's your friend who should _prove_ it to you that there is some
advantage to his method.

V
 
P

Phlip

Gaijinco said:
I have always felt that you should only declared variables as needed,
and implicitily it seems many authors to encourage it, but the other
day a friend told me that declaring variables inside a loop wasn't good
practice, something like:

for(int i=0; i<size-1; ++i){
int aux = array;
array=array[i+1];
array[i+1]=aux;
}

should be written like:

int aux;
for(int i=0; i<size-1; ++i){
aux = array;
array=array[i+1];
array[i+1]=aux;
}

What do you think? Thaks!


Your friend might think that the first code is slower. In some few similar
cases it might indeed be slower. You shouldn't worry about that.

Tell your friend that premature optimization is the root of all evil. The
most important resource to optimize is programmer time. Programmers must
write clean code first, because it's easy to make beautiful code fast than
fast code beautiful.

After your for loop ends, aux's only meaning is "the last variable in the
array". Subsequent statements should not rely on the for loop "leaking" its
last aux value out. If they want the last value in the array, they should
get it themselves. They should decouple as much as possible from the rest
of your program, including the statements just before them.

Always give any identifier the narrowest scope and access possible. Don't
use global variables or public data members. Never create a variable
without giving it an initial value. Put all these rules together, and you
have many reasons to put int aux inside the loop.
 
A

Artie Gold

Gaijinco said:
I have always felt that you should only declared variables as needed,
and implicitily it seems many authors to encourage it, but the other
day a friend told me that declaring variables inside a loop wasn't good
practice, something like:

for(int i=0; i<size-1; ++i){
int aux = array;
array=array[i+1];
array[i+1]=aux;
}

should be written like:

int aux;
for(int i=0; i<size-1; ++i){
aux = array;
array=array[i+1];
array[i+1]=aux;
}

What do you think? Thaks!

Since `aux' is only meaningful inside the loop why not limit its scope
to the block inside the loop?

On the other hand, there are situations where you wouldn't want to do
this, when, for example, the variable in question is of a type that
requires significant construction overhead. This, however, seems not to
be one of those situations. ;-)

HTH,
--ag
 
T

Tomás

Gaijinco posted:
I have always felt that you should only declared variables as needed,
and implicitily it seems many authors to encourage it, but the other
day a friend told me that declaring variables inside a loop wasn't good
practice, something like:

for(int i=0; i<size-1; ++i){
int aux = array;
array=array[i+1];
array[i+1]=aux;
}

should be written like:

int aux;
for(int i=0; i<size-1; ++i){
aux = array;
array=array[i+1];
array[i+1]=aux;
}

What do you think? Thaks!



Here's how I'd to do it:

for (int aux, i = 0; i < size -1; ++i)
{
...
}


If I had to pick one of the two ways you posted, then I'd put the
variable declaration outside the for loop. Does it make a difference?
Probably not... but at least your safe in the thought that memory isn't
being continuously allocated and deallocated for each iteration of the
loop.

Also as another Artie said, if you dealing with something like an
std::string, then definitely put it *outside* the loop.

The final reason is that I like consistency; if I'm going to put
std::string outside the loop, then I'll put an "int" outside the loop
too.

-Tomás
 
R

Roland Pibinger

I have always felt that you should only declared variables as needed,
and implicitily it seems many authors to encourage it, but the other
day a friend told me that declaring variables inside a loop wasn't good
practice, something like:

for(int i=0; i<size-1; ++i){
int aux = array;
array=array[i+1];
array[i+1]=aux;
}

should be written like:

int aux;
for(int i=0; i<size-1; ++i){
aux = array;
array=array[i+1];
array[i+1]=aux;
}


Why? Both versions are essentially the same. The performance is the
same. The second version is bad style because it doesn't obey to the
'minimal scoping rule'.
What do you think? Thaks!

Your friend has gone astray. Lead him back to the right path.
Roland Pibinger
 
P

Phlip

Tomas said:
Here's how I'd to do it:

for (int aux, i = 0; i < size -1; ++i)
{
...
}

Why?

The scope is not as narrow as possible. It's one tick wider, into a scope
where it's not needed.
If I had to pick one of the two ways you posted, then I'd put the
variable declaration outside the for loop. Does it make a difference?
Probably not... but at least your safe in the thought that memory isn't
being continuously allocated and deallocated for each iteration of the
loop.

That's premature optimization.

Further, the earliest definitions of C state that storage for all local
variables in a function allocate when the function enters, regardless of
their scope. I'm sure The Standard has since mutilated that requirement,
but I can't imagine a compiler doing it any other way.
Also as another Artie said, if you dealing with something like an
std::string, then definitely put it *outside* the loop.

Why? Have you time tested it?

What if std::string inside a loop fit in your CPU cache, but outside the
loop it overflowed your cache and caused memory thrashing?
The final reason is that I like consistency; if I'm going to put
std::string outside the loop, then I'll put an "int" outside the loop
too.

Then put it consistently inside the loop. This improves the odds it will go
away!
 
T

Tomás

Tomás posted:
Gaijinco posted:
I have always felt that you should only declared variables as needed,
and implicitily it seems many authors to encourage it, but the other
day a friend told me that declaring variables inside a loop wasn't good
practice, something like:

for(int i=0; i<size-1; ++i){
int aux = array; array=array[i+1]; array[i+1]=aux; }

should be written like:

int aux;
for(int i=0; i<size-1; ++i){
aux = array; array=array[i+1]; array[i+1]=aux; }

What do you think? Thaks!



Here's how I'd to do it:

for (int aux, i = 0; i < size -1; ++i)
{
...
}


If I had to pick one of the two ways you posted, then I'd put the
variable declaration outside the for loop. Does it make a difference?
Probably not... but at least your safe in the thought that memory isn't
being continuously allocated and deallocated for each iteration of the
loop.

Also as another Artie said, if you dealing with something like an
std::string, then definitely put it *outside* the loop.

The final reason is that I like consistency; if I'm going to put
std::string outside the loop, then I'll put an "int" outside the loop
too.

-Tomás



Furthermore, if your worried about scope, God gave us curly braces for a
reason:

int main()
{
//Some code

{
int aux;
for (int i; i < size -1; ++i)
{
//Some Code
}
}

//Some more code
}


-Tomás
 
M

Marcus Kwok

Tom?s said:
The final reason is that I like consistency; if I'm going to put
std::string outside the loop, then I'll put an "int" outside the loop
too.

Found these quotes in the FAQ:

"Consistency is good, but it is not the greatest good" [29.5]

"The real problem is that people tend to worship consistency, and they
tend to extrapolate from the obscure to the common. That's not wise."
[10.19]

(Granted, they are talking about different situations, but nonetheless
they are good pieces of advice to keep in mind in general.)
 
A

Artie Gold

Tomás said:
Gaijinco posted:

I have always felt that you should only declared variables as needed,
and implicitily it seems many authors to encourage it, but the other
day a friend told me that declaring variables inside a loop wasn't good
practice, something like:

for(int i=0; i<size-1; ++i){
int aux = array;
array=array[i+1];
array[i+1]=aux;
}

should be written like:

int aux;
for(int i=0; i<size-1; ++i){
aux = array;
array=array[i+1];
array[i+1]=aux;
}

What do you think? Thaks!




Here's how I'd to do it:

for (int aux, i = 0; i < size -1; ++i)
{
...
}


If I had to pick one of the two ways you posted, then I'd put the
variable declaration outside the for loop. Does it make a difference?
Probably not... but at least your safe in the thought that memory isn't
being continuously allocated and deallocated for each iteration of the
loop.

Also as another Artie said, if you dealing with something like an
std::string, then definitely put it *outside* the loop.


I think you've overstated my comments to an extent; I'm not sure I would
call a std::string something that involves `significant construction
overhead'. In any event, as noted elsethread, it's an optimization in
any case and not to be undertaken lightly.
The final reason is that I like consistency; if I'm going to put
std::string outside the loop, then I'll put an "int" outside the loop
too.

It's only worth the ugliness of doing that if it's demonstrably worth
that ugliness in terms of *needed* performance.

Whenever possible localilty is *good*!

Cheers,
--ag
 
T

Tomás

It's only worth the ugliness of doing that if it's demonstrably worth
that ugliness in terms of *needed* performance.

When I write extra-special long complicated loops, I resort to brute force.
Here's a copy-paste of some of my latest code:


manual_loop_scope:
{
std::size_t i = 0;
std::size_t i_word = NumericInfo::max_divisions_euro - 2;

manual_loop_begin_iteration:
{
bool const& condition = i < (NumericInfo::max_divisions_euro -
1);

if ( !condition ) goto manual_loop_end;

manual_loop_body:
{
if ( p_digit[0] || p_digit[1] || p_digit[2] )
{
if (others_beforehand)
{
StringSystem::AppendPALIncCounter( p_char, ( p_digit
[0] ? lang_attribs.separator_comma : lang_attribs.separator_and ) );
}

others_beforehand = true;
StringSystem::AppendPALIncCounter( p_char,
GetSubThousandWithUnitName( p_digit[0], p_digit[1], p_digit[2],
lang_attribs.unit_names[i_word] ) );
}
} // close manual_loop_body
}//close manual_loop_iteration

manual_loop_continue:
{
++i;
p_digit += 3;
--i_word;

goto manual_loop_begin_iteration;

}//close manual_loop_continue

manual_loop_end: ;
}


Beauty is irrelevant.

-Tomás
 
G

Gavin Deane

Tomás said:
It's only worth the ugliness of doing that if it's demonstrably worth
that ugliness in terms of *needed* performance.

When I write extra-special long complicated loops, I resort to brute force.
Here's a copy-paste of some of my latest code:


manual_loop_scope:
{
std::size_t i = 0;
std::size_t i_word = NumericInfo::max_divisions_euro - 2;

manual_loop_begin_iteration:
{
bool const& condition = i < (NumericInfo::max_divisions_euro -
1);

if ( !condition ) goto manual_loop_end;

manual_loop_body:
{
if ( p_digit[0] || p_digit[1] || p_digit[2] )
{
if (others_beforehand)
{
StringSystem::AppendPALIncCounter( p_char, ( p_digit
[0] ? lang_attribs.separator_comma : lang_attribs.separator_and ) );
}

others_beforehand = true;
StringSystem::AppendPALIncCounter( p_char,
GetSubThousandWithUnitName( p_digit[0], p_digit[1], p_digit[2],
lang_attribs.unit_names[i_word] ) );
}
} // close manual_loop_body
}//close manual_loop_iteration

manual_loop_continue:
{
++i;
p_digit += 3;
--i_word;

goto manual_loop_begin_iteration;

}//close manual_loop_continue

manual_loop_end: ;
}

You're joking, right? Have you ever worked on code that's developed or
maintained by more than one person?
Beauty is irrelevant.

If by "beauty" you mean "readability through conformance to accepted
normal practice" then, no it's not irrelevant. It's more important than
anything else.

You're trolling aren't you.

Gavin Deane
 
J

Jim Langston

Tomás said:
It's only worth the ugliness of doing that if it's demonstrably worth
that ugliness in terms of *needed* performance.

When I write extra-special long complicated loops, I resort to brute
force.
Here's a copy-paste of some of my latest code:


manual_loop_scope:
{
std::size_t i = 0;
std::size_t i_word = NumericInfo::max_divisions_euro - 2;

manual_loop_begin_iteration:
{
bool const& condition = i < (NumericInfo::max_divisions_euro -
1);

if ( !condition ) goto manual_loop_end;

manual_loop_body:
{
if ( p_digit[0] || p_digit[1] || p_digit[2] )
{
if (others_beforehand)
{
StringSystem::AppendPALIncCounter( p_char, (
p_digit
[0] ? lang_attribs.separator_comma : lang_attribs.separator_and ) );
}

others_beforehand = true;
StringSystem::AppendPALIncCounter( p_char,
GetSubThousandWithUnitName( p_digit[0], p_digit[1], p_digit[2],
lang_attribs.unit_names[i_word] ) );
}
} // close manual_loop_body
}//close manual_loop_iteration

manual_loop_continue:
{
++i;
p_digit += 3;
--i_word;

goto manual_loop_begin_iteration;

}//close manual_loop_continue

manual_loop_end: ;
}


Beauty is irrelevant.

-Tomás

Thank you. I haven't seen a good example of spagetti code for a number of
years.
 
T

Tomás

Gavin Deane posted:
Tomás said:
It's only worth the ugliness of doing that if it's demonstrably
worth that ugliness in terms of *needed* performance.

When I write extra-special long complicated loops, I resort to brute
force. Here's a copy-paste of some of my latest code:


manual_loop_scope: {
std::size_t i = 0;
std::size_t i_word = NumericInfo::max_divisions_euro - 2;

manual_loop_begin_iteration: {
bool const& condition = i <
(NumericInfo::max_divisions_euro - 1);

if ( !condition ) goto manual_loop_end;

manual_loop_body: {
if ( p_digit[0] || p_digit[1] || p_digit[2] )
{
if (others_beforehand)
{
StringSystem::AppendPALIncCounter( p_char, (
p_digit
[0] ? lang_attribs.separator_comma : lang_attribs.separator_and ) ); }

others_beforehand = true;
StringSystem::AppendPALIncCounter( p_char,
GetSubThousandWithUnitName( p_digit[0], p_digit[1], p_digit[2],
lang_attribs.unit_names[i_word] ) ); }
} // close manual_loop_body
}//close manual_loop_iteration

manual_loop_continue: { ++i;
p_digit += 3; --i_word;

goto manual_loop_begin_iteration;

}//close manual_loop_continue

manual_loop_end: ; }

You're joking, right? Have you ever worked on code that's developed or
maintained by more than one person?

No.

If by "beauty" you mean "readability through conformance to accepted
normal practice" then, no it's not irrelevant. It's more important than
anything else.

I don't go for "accepted normal practice" -- I write my own code my own way.
It's efficient, portable and bug free.

My labels make it quite clear what's going on.
You're trolling aren't you.

No, I'm actually writing loops using labels and the "goto" keyword. If you
find it that scary, maybe you sould Google for "goto" and see what all the
grown-ups do with it.


-Tomás
 
P

peter koch

Artie said:
Gaijinco said:
I have always felt that you should only declared variables as needed,
and implicitily it seems many authors to encourage it, but the other
day a friend told me that declaring variables inside a loop wasn't good
practice, something like:

for(int i=0; i<size-1; ++i){
int aux = array;
array=array[i+1];
array[i+1]=aux;
}

should be written like:

int aux;
for(int i=0; i<size-1; ++i){
aux = array;
array=array[i+1];
array[i+1]=aux;
}

What do you think? Thaks!

Since `aux' is only meaningful inside the loop why not limit its scope
to the block inside the loop?

On the other hand, there are situations where you wouldn't want to do
this, when, for example, the variable in question is of a type that
requires significant construction overhead. This, however, seems not to
be one of those situations. ;-)


Even in those cases you should go for the innermost scope until
performance and experimentation tells you otherwise. If e.g. the
variable was a std::string, semantics differ when you put the string
outside the loop, and the extra work to reset the string at each
iteration might well be comparable to the cost of one constructor and
one destructor.

/Peter
HTH,
--ag

--
Artie Gold -- Austin, Texas
http://goldsays.blogspot.com
"You can't KISS* unless you MISS**"
[*-Keep it simple, stupid. **-Make it simple, stupid.]
 
P

peter koch

Tomás said:
Gavin Deane posted:
Tomás said:
It's only worth the ugliness of doing that if it's demonstrably
worth that ugliness in terms of *needed* performance.

When I write extra-special long complicated loops, I resort to brute
force. Here's a copy-paste of some of my latest code:
[snip what supposedly should be C++ code}

You're joking, right? Have you ever worked on code that's developed or
maintained by more than one person?
No.

Beauty is irrelevant.

If by "beauty" you mean "readability through conformance to accepted
normal practice" then, no it's not irrelevant. It's more important than
anything else.

I don't go for "accepted normal practice" -- I write my own code my own way.
It's efficient, portable and bug free.

My labels make it quite clear what's going on.
You're trolling aren't you.

No, I'm actually writing loops using labels and the "goto" keyword. If you
find it that scary, maybe you sould Google for "goto" and see what all the
grown-ups do with it.

These must be the same grown-ups that never take back-ups and don't do
unittests?
Well.... theres not much worth backing up anyway.

/Peter
 
P

Phlip

Tomás said:
No, I'm actually writing loops using labels and the "goto" keyword. If you
find it that scary, maybe you sould Google for "goto" and see what all the
grown-ups do with it.

Instead of priding yourself on obfuscation, researching how to write the
_simplest_ possible code for a set of features will improve the odds that
you could add value to a team of software engineers.

Specifically, code that is absurdly elaborate in one direction becomes
hopelessly resistant to unexpected changes in other directions. Preserving
flexibility is the heart of the software process because it allows customers
to request unexpected new features.
 
G

Gavin Deane

Tomás said:
Gavin Deane posted:

I don't go for "accepted normal practice" -- I write my own code my own way.
It's efficient, portable and bug free.

Which proves my point that you've never had to work on a code base with
more than one developer. You left out the most important factor -
readability. Yes, that is more important than bug-free.

If you write clear code that conforms to the principle of least
surprise, but it has bugs, I can understand the code and fix the bugs,
and modify the code with a low risk of introducing new bugs, all very
easily. If you write the sort of obfuscated code you posted in this
thread and it has no bugs, the chance of me being able to modify it
without introducing new bugs, and the chance of quickly identifying and
fixing those bugs are greatly reduced.
No, I'm actually writing loops using labels and the "goto" keyword. If you
find it that scary, maybe you sould Google for "goto" and see what all the
grown-ups do with it.

If that's not trolling I don't know what is. Please stop.

Gavin Deane
 
T

TB

Tomás skrev:
It's only worth the ugliness of doing that if it's demonstrably worth
that ugliness in terms of *needed* performance.

When I write extra-special long complicated loops, I resort to brute force.
Here's a copy-paste of some of my latest code:


manual_loop_scope:
{
std::size_t i = 0;
std::size_t i_word = NumericInfo::max_divisions_euro - 2;

manual_loop_begin_iteration:
{
bool const& condition = i < (NumericInfo::max_divisions_euro -
1);

if ( !condition ) goto manual_loop_end;

manual_loop_body:
{
if ( p_digit[0] || p_digit[1] || p_digit[2] )
{
if (others_beforehand)
{
StringSystem::AppendPALIncCounter( p_char, ( p_digit
[0] ? lang_attribs.separator_comma : lang_attribs.separator_and ) );
}

others_beforehand = true;
StringSystem::AppendPALIncCounter( p_char,
GetSubThousandWithUnitName( p_digit[0], p_digit[1], p_digit[2],
lang_attribs.unit_names[i_word] ) );
}
} // close manual_loop_body
}//close manual_loop_iteration

manual_loop_continue:
{
++i;
p_digit += 3;
--i_word;

goto manual_loop_begin_iteration;

}//close manual_loop_continue

manual_loop_end: ;
}

I'm speechless... ugh
 
P

Phlip

TB said:
I'm speechless... ugh

I have seen worse. Take a programmer who grew up with assembly, and let them
write C. Then, without a little education, and besotted with the belief that
"goto is faster", they might write an entire, brilliant application using
assembly-style C, with all kinds of run-on functions, looping with goto,
etc.
 

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,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top