programming style: while(TRUE), for(;;), ...?

F

Felix Kater

Hi,

in some cases like dynamic memory allocation I find it convenient to
(ab-)use for() or while() like this:


/* (allocate memory) */

for(;;){ /* alternatively: while(TRUE){ */

/* (other code) */

break;
}

/* (free memory) */


The reason to do that is to remind the programmer who might not be me
not to forget things (like freeing memory) when inserting code later,
keep the order of commands (don't free too early) etc.


Two questions:

Are there generally better ways to do that?

Are there reasons to prefer one of the two ways (for vs, while) ?


Felix
 
S

Suman

Felix said:
Hi,

in some cases like dynamic memory allocation I find it convenient to
(ab-)use for() or while() like this:


/* (allocate memory) */

for(;;){ /* alternatively: while(TRUE){ */

/* (other code) */

break;
}

/* (free memory) */


The reason to do that is to remind the programmer who might not be me
not to forget things (like freeing memory) when inserting code later,
keep the order of commands (don't free too early) etc.
If you put an infinite loop in between, then that piece of code
will never ever come to free memory part.Right? So prevention has
caused
a disease here.
Two questions:

Are there generally better ways to do that?

Are there reasons to prefer one of the two ways (for vs, while) ?
Do you mean to say whether I'd prefer murder to assasination?
 
S

Suman

Lawrence said:
I'm not clear how the for() really helps here. Does it potentially use
break in multiple places to go to the cleanup code?


The break statement ensures it isn't infinite, unless the loop body
contains continue statements. Concur.
do {
/*stuff*/
} while ( 0 );

Or wrap the code in for/while in a function, and call it with proper
arguments. That should be easier, if the constraints under which one
works, allows that.
 
F

Felix Kater

Lawrence Kirby said:
I'm not clear how the for() really helps here. Does it potentially use
break in multiple places to go to the cleanup code?

Yes, the multiple break points/exits lead to the same cleanup code.

Second: The opened brace (often together with indentation or folding in
the editor) reminds you that your are programming on something like a
sub level which will end at some point and execute other (important)
code on the main level.
There's always goto. :)

Third: I also think of nested situations where gotos are of course hard
to control.

Fourth: I beleve that it is not always a good practise to source out
pieces of code into new functions when these functions are used only
once. Using the suggested practise (together with a editor which can do
folding) could be a good substitution for that.

for (;;) and while (1) are equivalent.

Ok. I'll ask in a compiler's news group to check wheater there are
differences.


Felix
 
L

Lawrence Kirby

I'm not clear how the for() really helps here. Does it potentially use
break in multiple places to go to the cleanup code?
If you put an infinite loop in between, then that piece of code
will never ever come to free memory part.Right? So prevention has
caused
a disease here.

The break statement ensures it isn't infinite, unless the loop body
contains continue statements.

There's always goto. :)

for (;;) and while (1) are equivalent.
Do you mean to say whether I'd prefer murder to assasination?

Hopefully it won't come to either.

Lawrence
 
A

Alan J. McFarlane

wrote:
Ok. I'll ask in a compiler's news group to check wheater there are
differences.
Well one difference is that many compilers will warn about "while(1)",
with
e.g.
warning C4127: conditional expression is constant
Whereas, they don't warn about "for (;;)" (presumably because it's much
more obvious to the reader (and to the writer of the code too)).

I haven't found a 'quiet' equivalent though for "do{ ... }while(0)" (as
recommended in http://www.eskimo.com/~scs/C-faq/q10.4.html).
 
B

Ben Bacarisse

in some cases like dynamic memory allocation I find it convenient to
(ab-)use for() or while() like this:
Two questions:

Are there generally better ways to do that?

I would not say "better" but (if I understand what you are doing) there
are alternatives such as:

switch (0 /* anything */) {
default:
<stuff with breaks>
}

which reads as if it is doing "default stuff" with no danger of
actually looping.
 
G

Giorgos Keramidas

Ben Bacarisse said:
I would not say "better" but (if I understand what you are doing) there
are alternatives such as:

switch (0 /* anything */) {
default:
<stuff with breaks>
}

which reads as if it is doing "default stuff" with no danger of
actually looping.

Why would this be better than using <stuff with breaks> without the
funny switch() construct though?
 
L

Lawrence Kirby

On Tue, 05 Jul 2005 17:54:41 +0300, Giorgos Keramidas wrote:

....
Why would this be better than using <stuff with breaks> without the
funny switch() construct though?

Without the switch() construct break wouldn't work. Presumably the idea is
to create a common jump-out point for the enclosed code.

Lawrence
 
G

Giorgos Keramidas

Lawrence Kirby said:
Without the switch() construct break wouldn't work. Presumably the idea is
to create a common jump-out point for the enclosed code.

Ah. I still don't see why a simple "goto err;" would ugly, but that's I
guess dangerously close to the place where religious flamefests live.

Anyway, thanks for the clarification :)
 
A

Alan Balmer

Fourth: I beleve that it is not always a good practise to source out
pieces of code into new functions when these functions are used only
once. Using the suggested practise (together with a editor which can do
folding) could be a good substitution for that.

Not always, perhaps, but often. Putting a cohesive piece of code in
its own function can enhance readability and understanding of the
code.
 
S

Sensei

Felix said:
for(;;){ /* alternatively: while(TRUE){ */

/* (other code) */

break;
}

/* (free memory) */


I prefer something like this.

char continueFlag = 1;

while (continueFlag)
{
...
}

A better control, even with break & co.
The reason to do that is to remind the programmer who might not be me
not to forget things (like freeing memory) when inserting code later,
keep the order of commands (don't free too early) etc.

For THIS reason? Why?
Are there generally better ways to do that?

Are there reasons to prefer one of the two ways (for vs, while) ?

for(;;) == while(1)

Do what you like... it's more sugar than real matter...
 
M

Malcolm

Felix Kater said:
Are there reasons to prefer one of the two ways (for vs, while) ?
while(1) is marginally better. for(;;) is what I call compileable gibberish.
It means nothing outside the specific context of C, whilst quite a few other
languages allow a constant conditional.

while(TRUE) would be even better, except for one thing. It means that some
idiot has defined TRUE to the preprocessor. Why this is a terrible idea
later, for now let's just say that this is ANSI's job not yours.

However all loops must terminate eventually. You should endevaour to put the
condition in the while statement if at all possible. Remember do ... while
is also available if the condition is not avialble on loop entry.
 
C

Christian Bau

Felix Kater said:
Hi,

in some cases like dynamic memory allocation I find it convenient to
(ab-)use for() or while() like this:


/* (allocate memory) */

for(;;){ /* alternatively: while(TRUE){ */

/* (other code) */

break;
}

/* (free memory) */


The reason to do that is to remind the programmer who might not be me
not to forget things (like freeing memory) when inserting code later,
keep the order of commands (don't free too early) etc.


Two questions:

Are there generally better ways to do that?

Are there reasons to prefer one of the two ways (for vs, while) ?

The best way to write a "goto" statement is to write a "goto" statement.
 
C

Christian Bau

"Malcolm said:
while(1) is marginally better. for(;;) is what I call compileable gibberish.
It means nothing outside the specific context of C, whilst quite a few other
languages allow a constant conditional.

Since comp.lang.c _always_ operates in the specific context of C, there
is nothing wrong at all with for (;;).
 
C

CBFalconer

Alan said:
Not always, perhaps, but often. Putting a cohesive piece of code
in its own function can enhance readability and understanding of
the code.

In addition you probably get all the efficiency of the muddied
source anyway. The OP did state that it was used once, so the
separated code should be declared static. A good optimizer may
very well inline it without being told, and for gcc and C99 you can
simply mark it as inline.

Write for clarity first. Diddle only if needed. Do not take the
word of the rule of seven in vain.
 
M

Mark

Malcolm said:
while(1) is marginally better. for(;;) is what I call compileable
gibberish. It means nothing outside the specific context of C, whilst
quite a few other languages allow a constant conditional.
Neither is better, or worse than the other... 98% of the time, the inclusion
of either
is a clue that the original coder wasn't smart enough to realize (s)he could
easily
create a flag and use it to terminate the loop! In these instances you'll
frequently
find ten or more breaks out of the loop and three or four return statements
INSIDE
which often return without properly closing open file descriptors and/or
without
freeing dynamically allocated memory. That's normally not a problem though
as
these loops, albeit a few thousand lines long, are typically found in the
program's
only function which is appropriately named, but often incorrectly defined:
main().
while(TRUE) would be even better, except for one thing. It means that some
idiot has defined TRUE to the preprocessor. Why this is a terrible idea
later, for now let's just say that this is ANSI's job not yours.
then why not:
while(EXIT_FAILURE)
or
while(! EXIT_SUCCESS)
I'll tell you why not... because it's stupid! :)
However all loops must terminate eventually.
Umm, no... some may need to run indefinately (as long as the system is
powered)
and in these instances it wouldn't matter if the coder chose to use while(1)
or for(;;)
You should endevaour to put the condition in the while statement if at all
possible. Remember do ... while is also available if the condition is not
avialble on loop entry.
Agreed.

Mark
 
B

Ben Bacarisse

Yes indeed. Thanks for the clarification.
Ah. I still don't see why a simple "goto err;" would ugly, but that's I
guess dangerously close to the place where religious flamefests live.

Quite. I just thought I'd throw in another way to get break to do
goto's dirty work!
 
A

Alan Balmer

while(1) is marginally better. for(;;) is what I call compileable gibberish.
It means nothing outside the specific context of C, whilst quite a few other
languages allow a constant conditional.

Not many C programs will successfully compile as other languages
anyway ;-)

In fact, with the compilers I use, I prefer for(;;), because it
doesn't generate a warning.

Q. What is ";;"?

A. Ever.

Usage: for ever.
 
M

Me

in some cases like dynamic memory allocation I find it convenient to
(ab-)use for() or while() like this:


/* (allocate memory) */

for(;;){ /* alternatively: while(TRUE){ */

/* (other code) */

break;
}

/* (free memory) */


The reason to do that is to remind the programmer who might not be me
not to forget things (like freeing memory) when inserting code later,
keep the order of commands (don't free too early) etc.

If I saw code like that I would wonder wtf you were smoking when you
wrote it. do { } while(0); is almost always the best way to express
creation of a new scope because it's a common idiom and the other
common way makes you wonder why there are random braces lying around in
the middle of your code. Unfortunately, the do { } while (0); steals
the ability of you to break; out of an outer loop but that doesn't
appear to be a concern for you.
Are there generally better ways to do that?

ret = error_state;

if ((foo = init1()) != sentinel_foo)
goto _err1;
if ((boo = init2()) != sentinel_boo)
goto _err2;
....
ret = non_error_state;
// fall through if you want to free stuff
// otherwise goto done; or return ret;

err2:
free2(boo);
err1:
free1(foo);
done:
return ret;

or alternatively you can initialize foo and boo to some sentinel state:

if (...)
goto err;
if (...)
goto err;
....
err:
if (boo == sentinel_boo)
free2(boo);
if (foo == sentinel_foo)
free1(foo);
return ret;

You can even get rid of the sentinel checks if free2 and free1 work
when you pass sentinels.
 

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,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top