By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,238 Members | 1,746 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,238 IT Pros & Developers. It's quick & easy.

Inherent inefficiency in domestic "for" loop?

P: n/a


Is the domestic usage of the C "for" loop inefficient when it comes to
simple incrementation? Here's a very simple program that prints out the
bit-numbers in a byte.

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;

for( i = 0; i != CHAR_BIT; ++i )
{
printf( "Bit Index %u\n", i );
}

system("PAUSE");
}
(Feel free to substitute "i != CHAR_BIT" with "i < CHAR_BIT".)
If I try to replicate that using "goto", I get the following:

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;
Loop_Enter:

i = 0;

Loop_Condition:

if ( !(i != CHAR_BIT) ) goto Loop_End;

Loop_Body:

printf( "Bit Index %u\n", i );

Loop_Continue:

++i;
goto Loop_Condition;

Loop_End:

;
system("PAUSE");
}
However, we can see that the very first conditional test is redundant --
it would be better to test the condition AFTER each iteration, rather
than before. Something like:

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;
Loop_Enter:

i = 0;

Loop_Body:

printf( "Bit Index %u\n", i );
Loop_Continue:

++i;

Loop_Condition:

if ( i != CHAR_BIT ) goto Loop_Body;

Loop_End:

;
system("PAUSE");
}
If we compare the execution of both code snippets, we can see:
Snippet 1: Tests the condition 9 times
Snippet 2: Tests the condition 8 times
Is the widely used C method of simple loop incrementation inherently
inefficient? At first glance, it appears so to me.
(Yes, I realise that most compilers will "unroll" that loop, so lets
pretend we're working with a more complicated loop whose amount of
iterations isn't determined until runtime.)
--

Frederick Gotham
Jun 25 '06 #1
Share this Question
Share on Google+
34 Replies


P: n/a
Frederick Gotham <fg*******@SPAM.com> writes:
Is the domestic usage of the C "for" loop inefficient when it comes to
simple incrementation? Here's a very simple program that prints out the
bit-numbers in a byte.
[...]
However, we can see that the very first conditional test is redundant --
it would be better to test the condition AFTER each iteration, rather
than before. Something like:
[...]
Is the widely used C method of simple loop incrementation inherently
inefficient? At first glance, it appears so to me.


Only if the loop always executes at least once. In the more
general case where you have something like
for (i = start; i < end; i++)
then you do want the test before the first iteration.

I would never translate a loop into the awful form of labels +
gotos that you suggest. Use a do { ... } while loop if you
really want to avoid the test on the first iteration. But this
is usually a pointless micro-optimization.

Also, I have no idea why you refer to this as the "domestic" for
loop. The word does not make sense in this context.
--
"IMO, Perl is an excellent language to break your teeth on"
--Micah Cowan
Jun 25 '06 #2

P: n/a
In article <Xn**************************@194.125.133.14>,
Frederick Gotham <fg*******@SPAM.com> wrote:
However, we can see that the very first conditional test is redundant --


In cases like this the compiler can see it too.

-- Richard
Jun 26 '06 #3

P: n/a
* Ben Pfaff -> Someone:
Also, I have no idea why you refer to this as the "domestic" for
loop. The word does not make sense in this context.


It seems that some AI story-generating programs are on the loose.
They're used by spammers and some Usenet posters, I guess with some
human fixup added. Some of the "poetry" that turns up in [no.test] is
amazing.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jun 26 '06 #4

P: n/a
>Is the domestic usage of the C "for" loop inefficient when it comes to
simple incrementation?
It's equally inefficient if you outsource it.
However, we can see that the very first conditional test is redundant --
It is *NOT* redundant if you're going to invoke this:(Yes, I realise that most compilers will "unroll" that loop, so lets
pretend we're working with a more complicated loop whose amount of
iterations isn't determined until runtime.) it would be better to test the condition AFTER each iteration, rather
than before.
If you are speaking in general, rather than with a specific example,
anything can be made to execute in 0 time and 0 bytes if it doesn't
have to give the correct result. A for loop is *supposed* to, under
the right conditions, execute 0 iterations. Especially when the
loop variable is being used as an array index, being able to loop
for 0 iterations is useful.
If we compare the execution of both code snippets, we can see:

Snippet 1: Tests the condition 9 times
Snippet 2: Tests the condition 8 times
Condition testing is not the only thing that takes time. And due to
specialized instructions for looping, it may be more efficient
to use the 9th test.
Is the widely used C method of simple loop incrementation inherently
inefficient? At first glance, it appears so to me.
You haven't demonstrated that. For the C method and your suggested
method, count branches. Which is more expensive by that measure?
(Yes, I realise that most compilers will "unroll" that loop, so lets
pretend we're working with a more complicated loop whose amount of
iterations isn't determined until runtime.)


Gordon L. Burditt
Jun 26 '06 #5

P: n/a
Alf P. Steinbach posted:
* Ben Pfaff -> Someone:
Also, I have no idea why you refer to this as the "domestic" for
loop. The word does not make sense in this context.


It seems that some AI story-generating programs are on the loose.
They're used by spammers and some Usenet posters, I guess with some
human fixup added. Some of the "poetry" that turns up in [no.test] is
amazing.

My original post in this thread is genuine.

I program in C and C++.

For a while now, I've been contemplating whether a "for" loop performs
one more evaluation than it should (when there'll always be at least one
iteration.)

My original post wasn't any sort of attack or diatribe on the programming
language either -- simply an expression of my pondering.

I'd be happy if you'd like to discuss the topic of this thread sincerely,
and would ask you to take anything orthogonal to the topic elsewhere --
particularly discussion alleging my original post to have some
association with spam.
--

Frederick Gotham
Jun 26 '06 #6

P: n/a
Gordon Burditt posted:
A for loop is *supposed* to, under
the right conditions, execute 0 iterations.

Yes, exactly. But about 90% of the time, we're dealing with a loop which
will always execute at least once. For this 90% of the time, there's one
extra redudant evaluation performed.

I don't think the "for" loop should have been shaped to accomodate the 10%
of the time where we might not want the loop to run at all. If anything,
there should have been another kind of loop availabe, analogous as to how a
"while loop" has a sister "do loop".

Even something like a "do for" loop would be nice:

unsigned i;

do for( i = 0; i != some_value; ++i)
{
/* Body */
}


--

Frederick Gotham
Jun 26 '06 #7

P: n/a
Ben Pfaff posted:

Also, I have no idea why you refer to this as the "domestic" for
loop. The word does not make sense in this context.

In using the word "domestic", I refer to the widespread, accepted way of
using a "for" loop to perform simple incremental loops.
--

Frederick Gotham
Jun 26 '06 #8

P: n/a
G'day,

Frederick Gotham wrote:
Is the domestic usage of the C "for" loop inefficient when it comes to
simple incrementation? Here's a very simple program that prints out the
bit-numbers in a byte.

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;

for( i = 0; i != CHAR_BIT; ++i )
{
printf( "Bit Index %u\n", i );
}

system("PAUSE");
}
(Feel free to substitute "i != CHAR_BIT" with "i < CHAR_BIT".)
If I try to replicate that using "goto", I get the following:

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;
Loop_Enter:

i = 0;

Loop_Condition:

if ( !(i != CHAR_BIT) ) goto Loop_End;

Loop_Body:

printf( "Bit Index %u\n", i );

Loop_Continue:

++i;
goto Loop_Condition;

Loop_End:

;
system("PAUSE");
}
However, we can see that the very first conditional test is redundant --
it would be better to test the condition AFTER each iteration, rather
than before. Something like:
Only if you know that there will always be at least one iteration in
which case a do loop is more appropriate.

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;
Loop_Enter:

i = 0;

Loop_Body:

printf( "Bit Index %u\n", i );
Loop_Continue:

++i;

Loop_Condition:

if ( i != CHAR_BIT ) goto Loop_Body;

Loop_End:

;
system("PAUSE");
}
If we compare the execution of both code snippets, we can see:
Snippet 1: Tests the condition 9 times
Allows for 0..n iterations
Snippet 2: Tests the condition 8 times
Allows for 1..n iterations


Is the widely used C method of simple loop incrementation inherently
inefficient? At first glance, it appears so to me.
(Yes, I realise that most compilers will "unroll" that loop, so lets
pretend we're working with a more complicated loop whose amount of
iterations isn't determined until runtime.)


And that number of iterations may be 0.

--
Cheers,
Gryff
Jun 26 '06 #9

P: n/a
Frederick Gotham wrote:
unsigned i;

do for( i = 0; i != some_value; ++i)
{
/* Body */
}


unsigned i;

i = 0;
do {
/* Body */
} while(i++ != some_value);

Sometimes, if I have what seems like a do loop
that I want to enter from the middle:

goto entry;
do {
/* first thing */
entry:
/* second thing */
} while(i++ != some_value);

I unroll it half way into:

/* second thing */
while(i++ != some_value) {
/* first thing */
/* second thing */
}

--
pete
Jun 26 '06 #10

P: n/a
Frederick Gotham <fg*******@SPAM.com> writes:
Ben Pfaff posted:
Also, I have no idea why you refer to this as the "domestic" for
loop. The word does not make sense in this context.
In using the word "domestic", I refer to the widespread, accepted way of
using a "for" loop to perform simple incremental loops.


Perhaps you should use a word more evocative of that meaning,
such as "traditional", "common", "ordinary".
--
int main(void){char p[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv wxyz.\
\n",*q="kl BIcNBFr.NKEzjwCIxNJC";int i=sizeof p/2;char *strchr();int putchar(\
);while(*q){i+=strchr(p,*q++)-p;if(i>=(int)sizeof p)i-=sizeof p-1;putchar(p[i]\
);}return 0;}
Jun 26 '06 #11

P: n/a
>> A for loop is *supposed* to, under
the right conditions, execute 0 iterations.
Yes, exactly. But about 90% of the time, we're dealing with a loop which
will always execute at least once. For this 90% of the time, there's one
extra redudant evaluation performed.


Unless the compiler unrolls it. And you haven't demonstrated that
performing the extra redundant evaluation isn't faster. And it is
possible for the compiler to generate code that skips the redundant
comparison if it can determine that it is redundant.

If you want a do while loop, you known where to find it.
I don't think the "for" loop should have been shaped to accomodate the 10%
of the time where we might not want the loop to run at all.
In other words: speed trumps all, incorrectness 10% of the time
is unimportant. And if correctness is unimportant, anything can
run in 0 time and 0 bytes.
If anything,
there should have been another kind of loop availabe, analogous as to how a
"while loop" has a sister "do loop".
Why is this worthwhile? Assuming such a loop WAS available, why
should I spend 1,000,000 comparisons in CPU time re-compiling a
program in order to save one comparison?
Even something like a "do for" loop would be nice:

unsigned i;

do for( i = 0; i != some_value; ++i)
{
/* Body */
}


The first time someone has to debug using a do for () instead of a for(),
you'll probably use up 100 years of savings from that redundant comparison.

Gordon L. Burditt
Jun 26 '06 #12

P: n/a
In article <Xn**************************@194.125.133.14>,
Frederick Gotham <fg*******@SPAM.com> wrote:
Yes, exactly. But about 90% of the time, we're dealing with a loop which
will always execute at least once.
I just grepped the for loops in a fairly substantial piece of code
that I wrote. About a third of the for loops can execute zero times.
But almost all of the loops that execute at least once are
initializing data, and are only executed once each. So the proportion
of at-least-once loops executed is probably very small.
For this 90% of the time, there's one
extra redudant evaluation performed.
The vast majority of the at-least-once loops were cases where the
initial value and the valued tested against were constant, so the
compiler can generate code that tests at the end if that is more
efficient. Don't assume that something is inefficient without
considering how it can be implemented.
I don't think the "for" loop should have been shaped to accomodate the 10%
of the time where we might not want the loop to run at all.


Perhaps the authors of C had a better insight into what the common case
is and what the costs are.

-- Richard
Jun 26 '06 #13

P: n/a

A few people have suggested using a "do" loop in order to skip the first
redundant comparison; the reason I don't do that is because a "for" loop is
handy because it has nice compartments in which to specify:

(1) What to do before the loop
(2) What condition to evaluate
(3) What to do after each iteration

--

Frederick Gotham
Jun 26 '06 #14

P: n/a
Frederick Gotham wrote:
Gordon Burditt posted:

A for loop is *supposed* to, under
the right conditions, execute 0 iterations.


Yes, exactly. But about 90% of the time, we're dealing with a loop which
will always execute at least once. For this 90% of the time, there's one
extra redudant evaluation performed.


... by the abstract machine. What the actual machine does,
operating under the "as if" rule, is another matter. The only
way to see what happens is to find a few compilers that allow
you to examine the generated machine code, and experiment with
them. The results, of course, pertain to the compilers and not
to C as such.

If you want a loop that does not make an "extra" comparison,
consider do...while. Consider also that this might change the
meaning of your program.

--
Eric Sosman
es*****@acm-dot-org.invalid
Jun 26 '06 #15

P: n/a
L7
Frederick Gotham wrote:
Gordon Burditt posted:
A for loop is *supposed* to, under
the right conditions, execute 0 iterations.

Yes, exactly. But about 90% of the time, we're dealing with a loop which
will always execute at least once. For this 90% of the time, there's one
extra redudant evaluation performed.


Depends on exactly what you are doing.
If you are dealing with pointers, this eliminates an explicit check for
null.
If you _know_ that you will always execute the loop at least once, sure
- a do while would prove useful (although, I don't think you are going
to see any performance increase...).

I don't think the "for" loop should have been shaped to accomodate the 10%
of the time where we might not want the loop to run at all. If anything,
there should have been another kind of loop availabe, analogous as to how a
"while loop" has a sister "do loop".

The for loop isn't 'shaped' in any certain way.
You always have the option to change the flow of your code: do while,
for, while.
Even something like a "do for" loop would be nice:

unsigned i;

do for( i = 0; i != some_value; ++i)
{
/* Body */
}


--

Frederick Gotham


Jun 26 '06 #16

P: n/a
L7
Frederick Gotham wrote:
A few people have suggested using a "do" loop in order to skip the first
redundant comparison; the reason I don't do that is because a "for" loop is
handy because it has nice compartments in which to specify:

(1) What to do before the loop
(2) What condition to evaluate
(3) What to do after each iteration

All of which can be coded in another manner.
In other words, it's the responsibility of the programmer to correctly
handle the specific circumstances - not the language.


--

Frederick Gotham


Jun 26 '06 #17

P: n/a
Frederick Gotham wrote:

A few people have suggested using
a "do" loop in order to skip the first
redundant comparison;
the reason I don't do that is because a "for" loop is
handy because it has nice compartments in which to specify:

(1) What to do before the loop
(2) What condition to evaluate
(3) What to do after each iteration


A do loop does what you want
but you don't like the way it looks.

Your complaint about for loops
doesn't really have a lot substance to it.

--
pete
Jun 26 '06 #18

P: n/a
Frederick Gotham wrote:
Is the domestic usage of the C "for" loop inefficient when it comes to
simple incrementation? Here's a very simple program that prints out the
bit-numbers in a byte.

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;

for( i = 0; i != CHAR_BIT; ++i )
{
printf( "Bit Index %u\n", i );
}

system("PAUSE");
} .... However, we can see that the very first conditional test is redundant --
it would be better to test the condition AFTER each iteration, rather
than before.


This is a Quality of Implementation issue. If the initial value and
limit value are compile-time constants and the initial value of i
satifies the loop condition, the compiler is free to execute the body
immediately and move the comparison to the end of the loop, after the
increment clause.

Bottom line: it's the compiler, not the language, that is inefficient.

--
Thad
Jun 26 '06 #19

P: n/a
In article <Xn**************************@194.125.133.14>
Frederick Gotham <fg*******@SPAM.com> wrote:
for( i = 0; i != CHAR_BIT; ++i )
[tests, at least in the abstract machine, whether 0 != CHAR_BIT]

Any "real" C compiler that optimizes will see that, at the top of
the loop the first time, i == 0 and 0 != CHAR_BIT, so will move
the test from the top of the loop to the bottom (or unroll the
loop, as you mention; or do both).

If the compiler does not optimize, you probably have more important
things to worry about than simple "for" loops. :-)
(Yes, I realise that most compilers will "unroll" that loop, so lets
pretend we're working with a more complicated loop whose amount of
iterations isn't determined until runtime.)


OK:

for (i = start; i != stop; i++)

where "start" and "stop" are not constants:

% cat t.c
extern void bar(void);
void foo(int start, int stop) {
int i;

for (i = start; i != stop; i++)
bar();
}

GCC produces:

% gcc -O3 -S t.c
% cat t.s
[some setup code omitted]
movl 12(%ebp), %esi # load stop into %esi
movl 8(%ebp), %ebx # load start into %ebx
cmpl %esi, %ebx # compare start (aka i) vs stop
je .L8 # skip loop entirely if already equal
.p2align 2,,3
.L6:
incl %ebx # i++ -- moved up from bottom of loop
call bar # bar()
cmpl %esi, %ebx # compare i vs stop
jne .L6 # keep looping if not equal
.L8:
[cleanup code omitted]

Clearly, it *is* necessary to compare start vs stop, in this case.

With loops over linked lists:

for (p = head; p != NULL; p = p->next)

the initial test is also important (and as with the above loop, gcc
tends to hoist out a "head != NULL" test and move the remaining tests
to the bottom of the loop, provided this is profitable on the target
hardware).
--
In-Real-Life: Chris Torek, Wind River Systems
Salt Lake City, UT, USA (4039.22'N, 11150.29'W) +1 801 277 2603
email: forget about it http://web.torek.net/torek/index.html
Reading email is like searching for food in the garbage, thanks to spammers.
Jun 26 '06 #20

P: n/a
Frederick Gotham wrote:
Is the domestic usage of the C "for" loop inefficient when it comes to
simple incrementation?
No.
Here's a very simple program that prints out the
bit-numbers in a byte.

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;

for( i = 0; i != CHAR_BIT; ++i )
{
printf( "Bit Index %u\n", i );
}

system("PAUSE");
}
(Feel free to substitute "i != CHAR_BIT" with "i < CHAR_BIT".)
No, I rather like formally precise tests. (Of course, if you screw them up,
you're much more likely to get an infinite loop then your fellow programmer
who used an inexact comparison and got infinity as wiggle room.)
If I try to replicate that using "goto", <snip>

Don't. There are good reasons to use goto. This isn't one of them.
However, we can see that the very first conditional test is redundant --
it would be better to test the condition AFTER each iteration, rather
than before. Something like:
<snip>
Then use a do-while statement, that's what it's there for.
If we compare the execution of both code snippets, we can see:
Snippet 1: Tests the condition 9 times
Snippet 2: Tests the condition 8 times
Is the widely used C method of simple loop incrementation inherently
inefficient? At first glance, it appears so to me.
Then glance harder. There's nothing "inherently" inefficient about it. For
most loops it's perfectly valid and desirable to potentially execute 0
times. A pretest loop will handle this; a posttest loop will not.
(Yes, I realise that most compilers will "unroll" that loop, so lets
pretend we're working with a more complicated loop whose amount of
iterations isn't determined until runtime.)

Then, as I said above, use do-while. You might as well communicate your
knowledge (or assumption) about the loop's behavior to the esteemed maintainers.

Upthread, I see you don't want to use do-while because you like the way the
for-statement looks better. To that my educated response would be: tough
noogies. You can't have your cake and eat it too.

S.
Jun 26 '06 #21

P: n/a
av
On Sun, 25 Jun 2006 23:40:39 GMT, Frederick Gotham
<fg*******@SPAM.com> wrote:
Is the domestic usage of the C "for" loop inefficient when it comes to
simple incrementation? Here's a very simple program that prints out the
bit-numbers in a byte.

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;

for( i = 0; i != CHAR_BIT; ++i )
{
printf( "Bit Index %u\n", i );
}
system("PAUSE");
}
(Feel free to substitute "i != CHAR_BIT" with "i < CHAR_BIT".)
If I try to replicate that using "goto", I get the following:

#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;
Loop_Enter:

i = 0;

Loop_Condition:

if ( !(i != CHAR_BIT) ) goto Loop_End;

Loop_Body:

printf( "Bit Index %u\n", i );

Loop_Continue:

++i;
goto Loop_Condition;

Loop_End:

;
system("PAUSE");
}
However, we can see that the very first conditional test is redundant --
yes but here the compiler sees it and does the right.

the original
"
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;

for( i = 0; i != CHAR_BIT; ++i )
printf( "Bit Index %u\n", i );
printf("Charatter\n");
getchar();
return 0;
}
"

the traslation
"; int main(void)
;
push ebp
mov ebp,esp
push ebx
;
; {
; unsigned i;
;
; for( i = 0; i != CHAR_BIT; ++i )
;
@1:
xor ebx,ebx
;
; printf( "Bit Index %u\n", i );
;
?live1@32: ; EBX = i
@2:
push ebx
push offset s@
call _printf
add esp,8
inc ebx
cmp ebx,8
jne short @2
.....
xor eax,eax
;
; }
it would be better to test the condition AFTER each iteration, rather
than before. Something like:
yes the C compiler here does it
#include <stdio.h>
#include <limits.h>
#include <stdlib.h>

int main(void)
{
unsigned i;
Loop_Enter:

i = 0;

Loop_Body:

printf( "Bit Index %u\n", i );
Loop_Continue:

++i;

Loop_Condition:

if ( i != CHAR_BIT ) goto Loop_Body;

Loop_End:

;
If we compare the execution of both code snippets, we can see:
Snippet 1: Tests the condition 9 times
Snippet 2: Tests the condition 8 times
Is the widely used C method of simple loop incrementation inherently
inefficient? At first glance, it appears so to me.
(Yes, I realise that most compilers will "unroll" that loop, so lets
pretend we're working with a more complicated loop whose amount of
iterations isn't determined until runtime.)

Jun 26 '06 #22

P: n/a

Frederick Gotham wrote:
Gordon Burditt posted:
A for loop is *supposed* to, under
the right conditions, execute 0 iterations.

Yes, exactly. But about 90% of the time, we're dealing with a loop which
will always execute at least once. For this 90% of the time, there's one
extra redudant evaluation performed.

I randomly looked at a few for loops spread into several of my programs
and found 14 for loops that might be executed zero-times out of 25.
Most of the time, these loops would execute with a few iterations, and
seldomly with zero iterations, but my programs would be buggy if this
seldom case was not taken in account.
14/25 = 56%, not 10%
25 loops is not a very large sample (moreover, it was C++ programs, not
C programs), but I think it is enough revelant.
I don't think the "for" loop should have been shaped to accomodate the 10%
of the time where we might not want the loop to run at all. If anything,
there should have been another kind of loop availabe, analogous as to how a
"while loop" has a sister "do loop".

The for loop is shaped such as the condition is true when the body is
entered... It is easy to understand & use (i.e. you don't have to think
about special cases during 5 minutes).

Jun 26 '06 #23

P: n/a
On Sun, 25 Jun 2006 23:40:39 GMT, in comp.lang.c , Frederick Gotham
<fg*******@SPAM.com> wrote:


Is the domestic usage of the C "for" loop inefficient when it comes to
simple incrementation?
(snip examples)
Is the widely used C method of simple loop incrementation inherently
inefficient? At first glance, it appears so to me.


"Its a poor workman who blames his tools". Not trying to be rude, but
if 'for' is inefficient in the cases above, you're doing it wrong.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jun 26 '06 #24

P: n/a
On Mon, 26 Jun 2006 00:16:30 GMT, in comp.lang.c , Frederick Gotham
<fg*******@SPAM.com> wrote:
Gordon Burditt posted:
A for loop is *supposed* to, under
the right conditions, execute 0 iterations.

Yes, exactly. But about 90% of the time, we're dealing with a loop which
will always execute at least once.


Indeed
For this 90% of the time, there's one
extra redudant evaluation performed.
Only if you write the algo wrong. :-)
Even something like a "do for" loop would be nice:


Kinda like do {stmt;} while(condition); then ?

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jun 26 '06 #25

P: n/a
On Mon, 26 Jun 2006 01:07:23 GMT, in comp.lang.c , Frederick Gotham
<fg*******@SPAM.com> wrote:

A few people have suggested using a "do" loop in order to skip the first
redundant comparison; the reason I don't do that is because a "for" loop is
handy because it has nice compartments in which to specify:

(1) What to do before the loop
(2) What condition to evaluate
(3) What to do after each iteration


Right. So you're ignoring the right way to avoid your problem because
you dislike its aesthetics...
--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
Jun 26 '06 #26

P: n/a
Mark McIntyre <ma**********@spamcop.net> skriver:
On Mon, 26 Jun 2006 01:07:23 GMT, in comp.lang.c , Frederick Gotham
<fg*******@SPAM.com> wrote:
Right. So you're ignoring the right way to avoid your problem because
you dislike its aesthetics...


One could also notice that in many cases the average C compiler
finguers out what the for loop does and creates the same code for the
for(;;) {} and do {} while() loops.

/ Anders
--
http://anders.arnholm.nu/ Keep on Balping
Jun 27 '06 #27

P: n/a
pete <pf*****@mindspring.com> wrote:

Sometimes, if I have what seems like a do loop
that I want to enter from the middle:


Which is exactly why I have proposed generalizing the do-while loop:

do statement while ( expression ) statement

with the obvious semantics: the first statement is executed, the
expression is evaluated and the loop exited if zero, otherwise the
second statment is executed and then control returns to the first
statement. If the second statement is a null statement, you get the
traditional do-while loop.

Unfortunately, no one has taken me up on it and actually implemented it.

-Larry Jones

ANY idiot can be famous. I figure I'm more the LEGENDARY type! -- Calvin
Jun 27 '06 #28

P: n/a
la************@ugs.com wrote:
pete <pf*****@mindspring.com> wrote:

Sometimes, if I have what seems like a do loop
that I want to enter from the middle:
Which is exactly why I have proposed generalizing the do-while loop:

do statement while ( expression ) statement

with the obvious semantics: the first statement is executed, the
expression is evaluated and the loop exited if zero, otherwise the
second statment is executed and then control returns to the first
statement. If the second statement is a null statement, you get the
traditional do-while loop.


Known in FORTH as "BEGIN statement(s) condition WHILE statement(s)
REPEAT" with the same semantics.
I always missed not having it in C.
Unfortunately, no one has taken me up on it and actually implemented it.

-Larry Jones

Jun 27 '06 #29

P: n/a
la************@ugs.com wrote:
pete <pf*****@mindspring.com> wrote:
Sometimes, if I have what seems like a do loop
that I want to enter from the middle:
Which is exactly why I have proposed generalizing the do-while loop:

do statement while ( expression ) statement

Syntactically, this is a bad idea.

do {
statement
} while (expression) /* Oops: forgot semicolon */

give_me_a_ping_vasily_one_ping_only_please();

Although easy enough to detect, C's potential for syntactical slip-ups is
big enough as it is.
with the obvious semantics: the first statement is executed, the
expression is evaluated and the loop exited if zero, otherwise the
second statment is executed and then control returns to the first
statement. If the second statement is a null statement, you get the
traditional do-while loop.

Unfortunately, no one has taken me up on it and actually implemented it.

for (;;)
statement
if (!expression) break;
statement
}

You can use while(1) if you prefer.

I don't know when you proposed this, but loop-with-test-in-the-middle is not
exactly news.

http://en.wikipedia.org/wiki/Control..._in_the_middle

Of course, the syntax is not in C, and although people could "take you up on
it" and implement it, there wouldn't be any point. I doubt the standard
would get amended for this.

S.
Jun 27 '06 #30

P: n/a
In article <mk************@jones.homeip.net>, <la************@ugs.com> wrote:
Which is exactly why I have proposed generalizing the do-while loop:

do statement while ( expression ) statement


Some Lisps have a loop construct in which any number of (while condition)
and (until condition) statements can appear in the body.

-- Richard
Jun 27 '06 #31

P: n/a
av
On Tue, 27 Jun 2006 16:15:59 GMT, la************@ugs.com wrote:
pete <pf*****@mindspring.com> wrote:
Sometimes, if I have what seems like a do loop
that I want to enter from the middle:


Which is exactly why I have proposed generalizing the do-while loop:

do statement while ( expression ) statement


"goto label; do{...;label: ;...}while(exp);"
is for me enought for doing all. it is the general loop (so no more
for, while etc.)
Jun 27 '06 #32

P: n/a
Skarmander <in*****@dontmailme.com> wrote:

I don't know when you proposed this, but loop-with-test-in-the-middle is not
exactly news.


Not at all. I'm just the first person I know of demented enough to
suggest extending the syntax of the existing do loop to provide it in C
with absolutely no disruption of existing code. It seems to produce the
same mixture of feelings of elegance and revulsion that Duff's Device
does. Whether that's good or bad, I'll leave to others to judge.

I originally proposed it (informally) for the initial ANSI standard, but
other committee members made discusted noises and threw things at me, so
I dropped it. :-)

-Larry Jones

Mr. Subtlety drives home another point. -- Calvin
Jun 27 '06 #33

P: n/a
la************@ugs.com wrote:
Skarmander <in*****@dontmailme.com> wrote:
I don't know when you proposed this, but loop-with-test-in-the-middle is not
exactly news.
Not at all. I'm just the first person I know of demented enough to
suggest extending the syntax of the existing do loop to provide it in C
with absolutely no disruption of existing code.


You forget the most important thing: without addition of new keywords!

Though admittedly the C committee seems less reserved about this than the
C++ committee.
It seems to produce the same mixture of feelings of elegance and
revulsion that Duff's Device does. Whether that's good or bad, I'll leave
to others to judge.

I originally proposed it (informally) for the initial ANSI standard, but
other committee members made discusted noises and threw things at me, so
I dropped it. :-)

Heresy requires a strong stomach. To propose changing the very grammar of
our beloved language without adding anything we couldn't already accomplish!
I'm surprised you didn't get tarred and feathered...

S.
Jun 27 '06 #34

P: n/a

la************@ugs.com wrote:
Skarmander <in*****@dontmailme.comwrote:

I don't know when you proposed this, but loop-with-test-in-the-middle is not
exactly news.

Not at all. I'm just the first person I know of demented enough to
suggest extending the syntax of the existing do loop to provide it in C
with absolutely no disruption of existing code. It seems to produce the
same mixture of feelings of elegance and revulsion that Duff's Device
does. Whether that's good or bad, I'll leave to others to judge.

I originally proposed it (informally) for the initial ANSI standard, but
other committee members made discusted noises and threw things at me, so
I dropped it. :-)
I like it!

Jul 17 '06 #35

This discussion thread is closed

Replies have been disabled for this discussion.