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

for(;;) or while(1)?

P: n/a
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,

Rick

Nov 13 '05 #1
Share this Question
Share on Google+
52 Replies


P: n/a
In article <3f********@clarion.carno.net.au>, Rick wrote:
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,


Some C compilers may generate slightly different machine code,
but they ought to always be functionally identical. Choosing
one instead of the other will not break a program or make it
unportable.
--
Andreas Kähäri
Nov 13 '05 #2

P: n/a
j

"Rick" <rrquick@nospam-com> wrote in message
news:3f********@clarion.carno.net.au...
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C?
No.
If so, should we then use for(;;)? Thanks,

You use for(;;) when you do not want to imply a test, otherwise for that
purpose, you use while(1)
The practical result will be the same for all but the very stupidest
compilers.
Rick



Nov 13 '05 #3

P: n/a
Rick wrote:

Hi,

For portability, can an issue arise if we use while(1)
for an infinite loop in C?
My compiler generates a warning for that kind of code,
when I have the warning level high, where I like it.
If so, should we then use for(;;)?


My compiler doesn't generate a warning for that code,
so that's what I use.

--
pete
Nov 13 '05 #4

P: n/a
"Rick" <rrquick@nospam-com> wrote in message
news:3f********@clarion.carno.net.au...
| For portability, can an issue arise if we use while(1) for an infinite
| loop in C? If so, should we then use for(;;)? Thanks,

It should come down to the same.

However, I use for(;;) because I use some compilers which send out
warnings of the kind: "Constant used as conditional expression".

go figure...
--
http://ivan.vecerina.com
Nov 13 '05 #5

P: n/a
Rick wrote:
For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,


There aren't any real portability issues, but the `1' seems too
arbitrary to me (as pointed out in <news:sl****************@ashi.FootPrints.net>,
which is where I first saw that objection, I think. Using `true'
seems less objectionable, somehow, if you have a C99 (or C++) compiler
(or define it yourself).

Jeremy.
Nov 13 '05 #6

P: n/a
Greetings.

In article <bl************@ID-114079.news.uni-berlin.de>, Jeremy Yallop
wrote:
For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,


There aren't any real portability issues, but the `1' seems too
arbitrary to me


More so than while(42)? There's plenty of precedent for using '1' as a
generic truth constant; less so for other nonzero numbers.

--
_
_V.-o Tristan Miller [en,(fr,de,ia)] >< Space is limited
/ |`-' -=-=-=-=-=-=-=-=-=-=-=-=-=-=-= <> In a haiku, so it's hard
(7_\\ http://www.nothingisreal.com/ >< To finish what you
Nov 13 '05 #7

P: n/a
Jeremy Yallop writes:
For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,
There aren't any real portability issues, but the `1' seems too
arbitrary to me (as pointed out in

<news:sl****************@ashi.FootPrints.net>, which is where I first saw that objection, I think. Using `true'
seems less objectionable, somehow, if you have a C99 (or C++) compiler
(or define it yourself).


I wouldn't expect *any* constant to get rid of the warning message. while
implies a condition that will vary. I can see the reason for the message
but I'm glad the compiler I have doesn't issue such a warning. I much
prefer the while(1) construct. The for(:::) looks to me like someone is
trying to impress someone with their arcane knowledge.
Nov 13 '05 #8

P: n/a
Rick wrote:
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,

Rick


Well using it directly in code it has no matter, but what about this:

#define forever for(;;)

do
{
...x...
} forever;

NR

Nov 13 '05 #9

P: n/a
> Jeremy Yallop writes:
I wouldn't expect *any* constant to get rid of the warning message.
Wasn't that what Ivan said.. the compiler issues a "Constant used as
conditional expression" warning. How will *any* constant get rid of the
warning when the warning is about the use of a constant itself?
I much prefer the while(1) construct. The for(:::) looks to me like someone is
trying to impress someone with their arcane knowledge.


I don't think it's about making impressions, I'd say it's a matter of
taste. I myself use for(;;).. I believe it's much clearer to what's
happening; and like you said "while implies a condition that will vary",
that's just why while(constant) can be a little misleading at first
glance. My compiler once gave me a warning for while(constant), I
wondered if using such a constract was non-portable, but that's clearly
not the case.

Rick

Nov 13 '05 #10

P: n/a
Noah Roberts wrote:
Rick wrote:
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,

Rick


Well using it directly in code it has no matter, but what about this:

#define forever for(;;)

do
{
...x...
} forever;

NR


I didn't think this was valid syntax (after macro substitution):
do
{
/* ...x... */
} for (;;); /* after preprocessor substitution */

My understanding is the syntax is:
do
{
} while();

I don't believe you can replace the "while" with "for" in this
syntax. I've never heard of a "do-for" loop.

--
Thomas Matthews

C++ newsgroup welcome message:
http://www.slack.net/~shiva/welcome.txt
C++ Faq: http://www.parashift.com/c++-faq-lite
C Faq: http://www.eskimo.com/~scs/c-faq/top.html
alt.comp.lang.learn.c-c++ faq:
http://www.raos.demon.uk/acllc-c++/faq.html
Other sites:
http://www.josuttis.com -- C++ STL Library book

Nov 13 '05 #11

P: n/a
"Rick" <rrquick@nospam-com> wrote in message
news:3f********@clarion.carno.net.au...
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,


for(;;) has seven characters, and
while(1) has eight, so the former should
weight slightly less, thus be a bit more
portable.

Also, if carrying the construct in a backback,
the rounded edges of 'f' 'o' and 'r' should
be more comfortable than those pointy 'w', 'h',
'i', and 'l' characters. :-)

Seriously, either one is equally portable. Use
whichever you find most natural, unless you have
coding standards to follow.

-Mike
Nov 13 '05 #12

P: n/a
Rick wrote:
Jeremy Yallop writes:

[snip]

I didn't write any of the quoted text. Please be more careful with
your attributions.

Jeremy.
Nov 13 '05 #13

P: n/a
pete wrote:

Rick wrote:

Hi,

For portability, can an issue arise if we use while(1)
for an infinite loop in C?


My compiler generates a warning for that kind of code,
when I have the warning level high, where I like it.
If so, should we then use for(;;)?


My compiler doesn't generate a warning for that code,
so that's what I use.

--
pete


It's just your compiler's rant about programming style. The while (1)
and for (;;) constructs are identical.
--
Joe Wright mailto:jo********@earthlink.net
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 13 '05 #14

P: n/a
Rick <rrquick@nospam-com> wrote in message news:<3f********@clarion.carno.net.au>...
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,

Rick


Well I use

while ( 1 )

if I wish to.

BUT

I use

for ( ; ; )

If I wish to.

In terms of performance any *intelligent* compiler would produce the
same binary code. Though a compiler made possibly as a *experimental
project* **might** not do the optimization and might include a sort of
condition for checking the truth value of the expression in while,
which would be true, always. OTOH if you love goto you might also
wanna use

inf_loop:
......
goto inf_loop;

The last one would have the same performence level as that of a for( ;
; ).

why not use

for ( ; 1 ; )

which is *completly* semantically equivalent to the while ( 1 )

--
Imanpreet Singh Arora
imanpreet_arora AT yahoo DOT co DOT in

Aut inveniam viam aut faciam
Nov 13 '05 #15

P: n/a
Sorry about that Jeremy, I meant to qoute Osmium.
Rick

Jeremy Yallop wrote:
Rick wrote:
Jeremy Yallop writes:


[snip]

I didn't write any of the quoted text. Please be more careful with
your attributions.

Jeremy.


Nov 13 '05 #16

P: n/a
Rick writes:
Sorry about that Jeremy, I meant to qoute Osmium.
Rick

Jeremy Yallop wrote:
Rick wrote:
Jeremy Yallop writes:


[snip]

I didn't write any of the quoted text. Please be more careful with
your attributions.


I didn't write it either. Try again.
--
Osmium
Nov 13 '05 #17

P: n/a
Thomas Matthews wrote:
Noah Roberts wrote:
Rick wrote:
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,

Rick


Well using it directly in code it has no matter, but what about this:

#define forever for(;;)

do
{
...x...
} forever;

NR


I didn't think this was valid syntax (after macro substitution):


That was, I believe, the point he was making (i.e. that for(;;) and while(1)
are not interchangeable in all cases).

For what it's worth, I think while(condition) is clearer than either for(;;)
or while(1).

--
Richard Heathfield : bi****@eton.powernet.co.uk
"Usenet is a strange place." - Dennis M Ritchie, 29 July 1999.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
K&R answers, C books, etc: http://users.powernet.co.uk/eton
Nov 13 '05 #18

P: n/a

On Tue, 30 Sep 2003, Ridimz wrote:

"osmium" <r1********@comcast.net> wrote in message

I didn't write it either. Try again.
--
Osmium


Yea you did! Read your reply again! It's attached just in case
you need to see which one!


Maybe osmium means that someone else has been posting to Usenet
using his account... ;-)

Please don't post attachments to non-binaries groups.
A simple link to Google Groups, or, even better, a quick
reminder to "look three messages up the darn thread and
*read* it" would have sufficed.

And in general, don't use spaces in filenames. Some
uudecode clients might not even parse your attachment
correctly (I dunno what any RFC on the topic says; I'm
just pointing out the possibility).

-Arthur

Nov 13 '05 #19

P: n/a
Thomas Matthews <Th**********************@sbcglobal.net> wrote in message news:<AO*****************@newssvr17.news.prodigy.c om>...
Noah Roberts wrote:
Rick wrote:
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,

Rick

Well using it directly in code it has no matter, but what about this:

#define forever for(;;)

do
{
...x...
} forever;

NR


I didn't think this was valid syntax (after macro substitution):
do
{
/* ...x... */
} for (;;); /* after preprocessor substitution */

My understanding is the syntax is:
do
{
} while();


Nitpick: replace while() with while(expr)
I don't believe you can replace the "while" with "for" in this
syntax. I've never heard of a "do-for" loop.


Me neither. A lot of books would need to be appended if it existed.
--
Imanpreet Singh Arora
iimmaannpprreeeett_aarroorraa@@yyaahhoooo..ccoo..i inn

Singularize the letters above to send mail.
Nov 13 '05 #20

P: n/a
Thomas Matthews <Th**********************@sbcglobal.net> wrote in message news:<AO*****************@newssvr17.news.prodigy.c om>...
Noah Roberts wrote:
Rick wrote:
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,

Rick

Well using it directly in code it has no matter, but what about this:

#define forever for(;;)

do
{
...x...
} forever;

NR


I didn't think this was valid syntax (after macro substitution):
do
{
/* ...x... */
} for (;;); /* after preprocessor substitution */

My understanding is the syntax is:
do
{
} while();


Nitpick: replace while() with while(expr)
I don't believe you can replace the "while" with "for" in this
syntax. I've never heard of a "do-for" loop.


Me neither. A lot of books would need to be appended if it existed.
--
Imanpreet Singh Arora
iimmaannpprreeeett_aarroorraa@@yyaahhoooo..ccoo..i inn

Singularize the letters above to send mail.
Nov 13 '05 #21

P: n/a
"Mike Wahler" <mk******@mkwahler.net> wrote in message news:<PZ*****************@newsread4.news.pas.earth link.net>...
"Rick" <rrquick@nospam-com> wrote in message
news:3f********@clarion.carno.net.au...
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,
for(;;) has seven characters, and
while(1) has eight, so the former should
weight slightly less, thus be a bit more
portable.


Mine for loop

for ( ; ; )

has 11 characters

so does my while

while ( 1 )

including whitespace I might add.

Also, if carrying the construct in a backback,
the rounded edges of 'f' 'o' and 'r' should
be more comfortable than those pointy 'w', 'h',
'i', and 'l' characters. :-)
I guess it all boils down to this *VERY* difference only.

Seriously, either one is equally portable. Use
whichever you find most natural, unless you have
coding standards to follow.


--
Imanpreet Singh Arora
imanpreet_arora AT yahoo DOT co DOT in
Nov 13 '05 #22

P: n/a
Richard Heathfield wrote:
Thomas Matthews wrote:

Noah Roberts wrote:
Well using it directly in code it has no matter, but what about this:

#define forever for(;;)

do
{
...x...
} forever;

NR

I didn't think this was valid syntax (after macro substitution):

That was, I believe, the point he was making (i.e. that for(;;) and while(1)
are not interchangeable in all cases).


Yeah, that was the point I was making. Some people like to create a
macro like that, I usually just use the actual loop when I am testing
code. I don't like to use forever loops in real code but if I where to
do so I might define something like that.
For what it's worth, I think while(condition) is clearer than either for(;;)
or while(1).


Yes, it is much better to use a condition to exit. Many times people do
something like the following:

while (always)
get input
if input is quit then die

do something
....

but it is much better do do something like this:

boolean quit = false /* or continue = true */

while (!quit)
get input
if input is quit then quit = true
else do something
....

The second version is "structured" code whereas the first is not (two
exits). Sometimes it is better to break structure, but it always
sacrifices maintainability and readability; this is why goto was
declaired to be evil, yet in some algorithms (for instance verified null
move pruning in chess AI's) it is useful.

99.9999999% of the time it is not necissary to write unstructured code
and since it is a mistake to do so you shouldn't except for that
..000000001% of the time when you need to.

NR

Nov 13 '05 #23

P: n/a
Joe Wright wrote:

pete wrote:

Rick wrote:

Hi,

For portability, can an issue arise if we use while(1)
for an infinite loop in C?
My compiler generates a warning for that kind of code,
when I have the warning level high, where I like it.
If so, should we then use for(;;)?


My compiler doesn't generate a warning for that code,
so that's what I use.

It's just your compiler's rant about programming style. The while (1)
and for (;;) constructs are identical.


That's why I let the rant be the tie breaker.

--
pete
Nov 13 '05 #24

P: n/a
"Minti" <mi************@yahoo.com> wrote in message
news:e8**************************@posting.google.c om...
"Mike Wahler" <mk******@mkwahler.net> wrote in message

news:<PZ*****************@newsread4.news.pas.earth link.net>...
"Rick" <rrquick@nospam-com> wrote in message
news:3f********@clarion.carno.net.au...
Hi,

For portability, can an issue arise if we use while(1) for an infinite
loop in C? If so, should we then use for(;;)? Thanks,


for(;;) has seven characters, and
while(1) has eight, so the former should
weight slightly less, thus be a bit more
portable.


Mine for loop

for ( ; ; )

has 11 characters

so does my while

while ( 1 )

including whitespace I might add.

Also, if carrying the construct in a backback,
the rounded edges of 'f' 'o' and 'r' should
be more comfortable than those pointy 'w', 'h',
'i', and 'l' characters. :-)


I guess it all boils down to this *VERY* difference only.


Everyone knows that whitespace characters are weightless. :-)

-Mike
Nov 13 '05 #25

P: n/a
Noah Roberts writes:
but it is much better do do something like this:

boolean quit = false /* or continue = true */


I wouldn't expect the alternative to work.
Pedants, especially, should test their code before positng.
Nov 13 '05 #26

P: n/a
osmium wrote:
Noah Roberts writes:

but it is much better do do something like this:

boolean quit = false /* or continue = true */

I wouldn't expect the alternative to work.
Pedants, especially, should test their code before positng.


If you use continue = true you must alter the loop just slightly.

while (continue)
{

if (wanttoquit) continue = false;
else dostuff...
}

I guess some people must have it spelled out for them, I assumed too
much. And no, I was not being pedantic but you have the right to that
opinion.

NR

Nov 13 '05 #27

P: n/a
Noah Roberts <nr******@dontemailme.com> wrote:
while (continue)


Erm... choose a different name.

Richard
Nov 13 '05 #28

P: n/a
In article <bl**********@quark.scn.rain.com>, Noah Roberts wrote:
osmium wrote:
Noah Roberts writes:

but it is much better do do something like this:

boolean quit = false /* or continue = true */

I wouldn't expect the alternative to work.
Pedants, especially, should test their code before positng.


If you use continue = true you must alter the loop just slightly.

while (continue)
{

if (wanttoquit) continue = false;
else dostuff...
}

I guess some people must have it spelled out for them, I
assumed too much. And no, I was not being pedantic but you
have the right to that opinion.


continue is a keyword.

--
Neil Cerutti
Nov 13 '05 #29

P: n/a
Noah Roberts wrote:
Yes, it is much better to use a condition to exit. Many times people do
something like the following:

while (always)
get input
if input is quit then die

do something
...

but it is much better do do something like this:

boolean quit = false /* or continue = true */
I'm sure that, being a well-structuring kind of chap, you just forgot
that `continue` is a C keyword ...
while (!quit)
get input
if input is quit then quit = true
else do something
...

The second version is "structured" code whereas the first is not (two
exits).
The second one is horrid. The artifical boolean variable obscures what's
going on.

Assuming `always` is well-named, the first one has on exit. N-and-a-half
loops are just as structured as N loops. The idiom

while (yourChoiceForTrue)
{ preamble;
if (doneExpression) break;
postamble; }

is well-structured and worth knowing.
Sometimes it is better to break structure, but it always
sacrifices maintainability and readability;


Not *always*.

The rule that makes sense to me is "code clearly". If it's a choice
between between being clear and being structured, being clear wins.
Usually you don't need to make the choice.

--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgrou...mp.lang.c.html
C welcome: http://www.angelfire.com/ms3/bchambl...me_to_clc.html
Nov 13 '05 #30

P: n/a
Chris Dollin writes:
boolean quit = false /* or continue = true */


I'm sure that, being a well-structuring kind of chap, you just forgot
that `continue` is a C keyword ...


touché :-)
Nov 13 '05 #31

P: n/a
Chris Dollin wrote:
Noah Roberts wrote:
.... snip ...
N-and-a-half loops are just as structured as N loops. The idiom

while (yourChoiceForTrue)
{ preamble;
if (doneExpression) break;
postamble; }

is well-structured and worth knowing.
Sometimes it is better to break structure, but it always
sacrifices maintainability and readability;


Not *always*.

The rule that makes sense to me is "code clearly". If it's a
choice between between being clear and being structured, being
clear wins. Usually you don't need to make the choice.


For purposes of clarity, I will always prefer:

while (yourChoiceForTrue) {
preamble;
if (doneExpression) goto done;
postamble;
}
done:

because the presence of "done:" alerts the reader to look for its
use. Without this flag the reader can easily miss the buried in
verbosity break in the original.

A clearer method may well be to combine doneExpression and
preamble in a separate routine and simplify the loop to:

while (preamble(preambleparams)) {
postamble;
}

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 13 '05 #32

P: n/a
Noah Roberts <nr******@dontemailme.com> writes:
Yeah, that was the point I was making. Some people like to
create a macro like that, I usually just use the actual loop when
I am testing code. I don't like to use forever loops in real
code but if I where to do so I might define something like that.
For what it's worth, I think while(condition) is clearer than
either for(;;) or while(1).
Yes, it is much better to use a condition to exit. Many times
people do something like the following:

while (always)
get input
if input is quit then die

do something
...

but it is much better do do something like this:

boolean quit = false /* or continue = true */

while (!quit)
get input
if input is quit then quit = true
else do something
...


"Much better"... IYO. I frequently prefer the former, and call it
a "mid-test" loop. IMO, mainstream programming languages have
syntax for a pretest loop and posttest loop, but no one supports
the midtest loop. So I use the former example above, which is the
closest thing available, rather than try to force it to be a
pretest loop.

Another way of forcing it to look like a pretest loop (but it
still isn't) is something like:

while ((c = getchar()) != EOF)
...
The second version is "structured" code whereas the first is not
(two exits).
Wrong. There is exactly one exit. It seems very structured to me,
if used properly: even if the syntax may not be as clean, it's
less ugly (to me) than going through loops to make it "proper".
Sometimes it is better to break structure, but it
always sacrifices maintainability and readability;
Not true. I frequently break structure for the explicit purpose
to improve portability. The typical case being something like:

int error_code = NO_ERROR;

a = malloc(sz_a);
if (a == NULL) { error_code = MEM_ERROR; goto my_end; }
(...calculations using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculations using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculations using a, b and c...)

free (c);
cleanup_b:
free (b);
cleanup_a:
free (a);

my_end:
return error_code;

The alternatives include nesting a ton of if statements (which in
many cases can get cumbersome quickly), code repetition (always
something I strive to avoid; it usually leads to
bugs/inconsistencies), and checking some combination of a, b or c
before each and every operation involving them (ouch!!!). There's
also farming each block out to a separate function, which is
often what I try first, but sometimes this can be even more
cumbersome, especially if there are a lot of other variables
involved that would need to be passed around.
99.9999999% of the time it is not necissary to write unstructured
code and since it is a mistake to do so you shouldn't except for
that .000000001% of the time when you need to.


This percentage is somewhat exaggerated (to me). I've found it closer to
between 97-99% of the time, personally.

-Micah
Nov 13 '05 #33

P: n/a
"Mike Wahler" <mk******@mkwahler.net> wrote in message news:<qY******************@newsread3.news.pas.eart hlink.net>...
"Minti" <mi************@yahoo.com> wrote in message
news:e8**************************@posting.google.c om...
"Mike Wahler" <mk******@mkwahler.net> wrote in message

news:<PZ*****************@newsread4.news.pas.earth link.net>...
"Rick" <rrquick@nospam-com> wrote in message
news:3f********@clarion.carno.net.au...
> Hi,
>
> For portability, can an issue arise if we use while(1) for an infinite
> loop in C? If so, should we then use for(;;)? Thanks,

for(;;) has seven characters, and
while(1) has eight, so the former should
weight slightly less, thus be a bit more
portable.


Mine for loop

for ( ; ; )

has 11 characters

so does my while

while ( 1 )

including whitespace I might add.

Also, if carrying the construct in a backback,
the rounded edges of 'f' 'o' and 'r' should
be more comfortable than those pointy 'w', 'h',
'i', and 'l' characters. :-)


I guess it all boils down to this *VERY* difference only.


Everyone knows that whitespace characters are weightless. :-)


Oops sorry! I forgot we were talking about weights. I thought we were
talking about ................. never mind.

--
Imanpreet Singh Arora
imanpreet_arora AT yahoo DOT co DOT in
Nov 13 '05 #34

P: n/a
Chris Dollin wrote:
Noah Roberts wrote:

Yes, it is much better to use a condition to exit. Many times people do
something like the following:

while (always)
get input
if input is quit then die

do something
...

but it is much better do do something like this:

boolean quit = false /* or continue = true */

I'm sure that, being a well-structuring kind of chap, you just forgot
that `continue` is a C keyword ...


If you think that is funny:

-----Contents of funny.c (good name)----
boolean quit = false /* or continue = true */

while (!quit)
get input
if input is quit then quit = true
else do something
....
-----end contents----

----attempt compile----
jik-@darkstar:~$ gcc -pedantic funny.c
funny.c:1: error: parse error before "quit"
funny.c:3: error: `false' undeclared here (not in a function)
funny.c:3: error: parse error before "while"
-----end attempt----

Unfortunately it quit even trying at that point. It might have been
more entertaining had it continued. Putting it inside of a main loop is
even less entertaining because it stops trying to process the file much
sooner.

What an odd thing to focus on, yet several responders did.

while (!quit)
get input
if input is quit then quit = true
else do something
...

The second version is "structured" code whereas the first is not (two
exits).

The second one is horrid. The artifical boolean variable obscures what's
going on.


How so? It says "loop until I am told to quit" instead of "loop
forever". In my opinion "while (true)" is the lie because true never
stops being true yet you exit at some point.

Also you are assuming that quit is set to false within the loop, as it
is in the /pseudo/ code I wrote. This is only the case for very simple
programs or problems. More often your stop switch will be turned on
somewhere in a function you call in your loop, maybe several levels in.
If you want to exit the program at this point then you can call a
function that kills your process and never have to exit your forever
loop. Otherwise the best way is to use a stop switch use it to exit
your loop.

For simple problems the break or return method is acceptable but doesn't
hold up when things get much more complex.
Sometimes it is better to break structure, but it always
sacrifices maintainability and readability;

Not *always*.

The rule that makes sense to me is "code clearly". If it's a choice
between between being clear and being structured, being clear wins.


I agree. I don't like "loop forever" but I do do things like this:

while test_case
if exception break
continue processing
end

I try to stay away from those though as it can really bite you in the
ass, and I only ever use forever loops in tests, never in production code.

NR

Nov 13 '05 #35

P: n/a
Micah Cowan wrote:
Noah Roberts <nr******@dontemailme.com> writes:
Sometimes it is better to break structure, but it
always sacrifices maintainability and readability;

Not true. I frequently break structure for the explicit purpose
to improve portability. The typical case being something like:

int error_code = NO_ERROR;

a = malloc(sz_a);
if (a == NULL) { error_code = MEM_ERROR; goto my_end; }
(...calculations using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculations using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculations using a, b and c...)

free (c);
cleanup_b:
free (b);
cleanup_a:
free (a);

my_end:
return error_code;


I think the above code is a pretty good representation of why I think
doing such things is a bad idea. That is just gross, but of course that
is my opinion.
The alternatives include nesting a ton of if statements (which in
many cases can get cumbersome quickly), code repetition (always
something I strive to avoid; it usually leads to
bugs/inconsistencies), and checking some combination of a, b or c
before each and every operation involving them (ouch!!!). There's
also farming each block out to a separate function, which is
often what I try first, but sometimes this can be even more
cumbersome, especially if there are a lot of other variables
involved that would need to be passed around.


How about this ;)

malloc(a...)
malloc(b...)
malloc(c...)

if (a && b && c) // or probably more readable to compare to null
explicetly...
do calcs...
else
clean up the mess // ie...if a free a, if b free b ...

In normal situations you will not find any major gain from doing it your
way, and I especially prefer mine in this case. In some abnormal
situation you may find you will gain performance enough to warrant all
that goto spagetti (my opinion) or even less often my way is impossible
if the allocations somehow depend on each other. A few extra tests is
not worth it IMHO and I think you have just as many jumps so the
performance gain depends only on the allocations not done.

Perhaps some other situation besides allocating memory would lead to
requiring something as ugly as the above. I would hope to never find
such a situation and would try very hard to find some other solution.
In fact I would probably prefer the nesting ifs myself.

But like I said, the verified null move algorithm involves the use of a
single goto statement and it is just the best and most readable way to
go about the problem. That is one rare case.

NR

Nov 13 '05 #36

P: n/a
Noah Roberts wrote:
Chris Dollin wrote:
I'm sure that, being a well-structuring kind of chap, you just forgot
that `continue` is a C keyword ...


If you think that is funny:


Amusing. Not funny. An aside.
What an odd thing to focus on, yet several responders did.
Of course. Nitpickery isn't offswitchable.
while (!quit)
get input
if input is quit then quit = true
else do something
...

The second version is "structured" code whereas the first is not (two
exits).


The second one is horrid. The artifical boolean variable obscures what's
going on.


How so? It says "loop until I am told to quit" instead of "loop
forever". In my opinion "while (true)" is the lie because true never
stops being true yet you exit at some point.


`while(true)` is the signal that says "less common loop structure
here". Using a quit variable says "there's some boolean you have to
track through this code to look for assignments and check their
value". With `while (true)` you know it's breaks you have to look
for, which you knew anyway.

`lie` doesn't come into it.
Also you are assuming that quit is set to false within the loop, as it
is in the /pseudo/ code I wrote. This is only the case for very simple
programs or problems. More often your stop switch will be turned on
somewhere in a function you call in your loop, maybe several levels in.
That has happened to me maybe twice in twenty years.
For simple problems the break or return method is acceptable but doesn't
hold up when things get much more complex.
Maybe I don't write complex enough code.
I try to stay away from those though as it can really bite you in the
ass, and I only ever use forever loops in tests, never in production code.


Tests *are* production code :-)

--
Chris "electric hedgehog" Dollin
C FAQs at: http://www.faqs.org/faqs/by-newsgrou...mp.lang.c.html
C welcome: http://www.angelfire.com/ms3/bchambl...me_to_clc.html
Nov 13 '05 #37

P: n/a
Noah Roberts <nr******@dontemailme.com> writes:
Micah Cowan wrote:
Noah Roberts <nr******@dontemailme.com> writes:
Sometimes it is better to break structure, but it
always sacrifices maintainability and readability; Not true. I frequently break structure for the explicit purpose
to improve portability. The typical case being something like:
int error_code = NO_ERROR;
a = malloc(sz_a);
if (a == NULL) { error_code = MEM_ERROR; goto my_end; }
(...calculations using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculations using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculations using a, b and c...)
free (c);
cleanup_b:
free (b);
cleanup_a:
free (a);
my_end:
return error_code;


I think the above code is a pretty good representation of why I
think doing such things is a bad idea. That is just gross, but
of course that is my opinion.

The alternatives include nesting a ton of if statements (which
in
many cases can get cumbersome quickly), code repetition (always
something I strive to avoid; it usually leads to
bugs/inconsistencies), and checking some combination of a, b or c
before each and every operation involving them (ouch!!!). There's
also farming each block out to a separate function, which is
often what I try first, but sometimes this can be even more
cumbersome, especially if there are a lot of other variables
involved that would need to be passed around.


How about this ;)

malloc(a...)
malloc(b...)
malloc(c...)

if (a && b && c) // or probably more readable to compare to null
explicetly...
do calcs...
else
clean up the mess // ie...if a free a, if b free b ...


That's all well and good: but what if you needed to use a before
you had the details on exactly what size you needed b to be?

In normal situations you will not find any major gain from doing
it your way, and I especially prefer mine in this case.
When yours is possible, so would I. Frequently it is not. And
these situations are *quite* normal. There are many programming
shops which consider examples such as the above to be the one
exception to the goto rule (though many more would have you never
use goto at all). I have no "goto" rule, only "readability" and
"no code repetition" rules and the like. Most of the time, they
eliminate the use of gotos, but in those cases when the use of
goto will improve readability and reduce redundant code, I will
not hesitate to use it.
Perhaps some other situation besides allocating memory would lead
to requiring something as ugly as the above. I would hope to
never find such a situation and would try very hard to find some
other solution. In fact I would probably prefer the nesting ifs
myself.


Ugh.... that's awful. What do you find ugly about the above? It's
simple and elegant, and you know where to find everything. The
nested ifs feels like wading through muck, to me.

-Micah
Nov 13 '05 #38

P: n/a
Micah Cowan <mi***@cowan.name> wrote in message news:<m3************@localhost.localdomain>...

[snip]

Not true. I frequently break structure for the explicit purpose
to improve portability. The typical case being something like:

int error_code = NO_ERROR;

a = malloc(sz_a);
if (a == NULL) { error_code = MEM_ERROR; goto my_end; }
(...calculations using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculations using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculations using a, b and c...)

free (c);
cleanup_b:
free (b);
cleanup_a:
free (a);

my_end:
return error_code;


I'm not sure exactly how that improves portability?

My problem with this structure is that it does not clearly convey that
c is dependent on b and a, and that b is dependent on a. I would
rather have that relationship visually reinforced by nesting even if
it means marching halfway across the page, because then I can see the
relationship and its extent at a glance, instead of groveling through
the source.
Nov 13 '05 #39

P: n/a
On Thu, 02 Oct 2003 17:01:42 -0700, John Bode wrote:
Micah Cowan <mi***@cowan.name> wrote in message news:<m3************@localhost.localdomain>...

[snip]

Not true. I frequently break structure for the explicit purpose
to improve portability. The typical case being something like:

int error_code = NO_ERROR;

a = malloc(sz_a);
if (a == NULL) { error_code = MEM_ERROR; goto my_end; }
(...calculations using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculations using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculations using a, b and c...)

free (c);
cleanup_b:
free (b);
cleanup_a:
free (a);

my_end:
return error_code;


My problem with this structure is that it does not clearly convey that
c is dependent on b and a, and that b is dependent on a. I would
rather have that relationship visually reinforced by nesting ...


What if these nested dependencies don't exist? Suppose the code is

int foo (FILE * f)
{
int error_code = NO_ERROR;

atype * a = NULL;
btype * b = NULL;
ctype * c = NULL;

a = malloc(sz_a);
if (a == NULL) goto mem_error;
if (fread(a, sizeof *a, 1, f) < 1) goto file_error;

b = malloc(sz_b);
if (b == NULL) goto cleanup_a;
if (fread(b, sizeof *b, 1, f) < 1) goto file_error;

c = malloc(sz_c);
if (c == NULL) goto cleanup_ab;
if (fread(c, sizeof *c, 1, f) < 1) goto file_error;

/* calculations using a, b and c */

goto cleanup_and_return;

mem_error:
error_code = MEM_ERROR;
goto cleanup_and_return;

file_error:
error_code = FILE_ERROR;
goto cleanup_and_return;

cleanup_and_return:
free(c);
free(b);
free(a);
return error_code;
}

I have written code like this before because I find it much
easier to sort out than the alternative. The least confusing
code is straight-line code. The most confusing is spaghetti code.
The reason goto was 'considered harmful' is because it enables
spaghetti code, not because the function is performs is itself
undesirable. In the example above, the control flow is very close
to straight-line: all gotos branch in one direction, and the
code reads from top to bottom. Moreover, the error handling has
all been banished to it's own segment of code and doesn't clutter
up the main logic of the function. Finally, the main part of the
function (the elided 'calculations') are at the top level of
the function instead of being buried in a huge pile of nested
braces.

-Sheldon

http://groups.google.com/groups?hl=e...%40wlcrjs.UUCP
http://groups.google.com/groups?hl=e...%40decvax.UUCP
http://groups.google.com/groups?hl=e...40umcp-cs.UUCP
http://groups.google.com/groups?hl=e...brl-smoke.ARPA

Nov 13 '05 #40

P: n/a
John Bode wrote:

Micah Cowan <mi***@cowan.name> wrote in message news:<m3************@localhost.localdomain>...

[snip]
Not true. I frequently break structure for the explicit purpose
to improve portability. The typical case being something like:

int error_code = NO_ERROR;

a = malloc(sz_a);
if (a == NULL) { error_code = MEM_ERROR; goto my_end; }
(...calculations using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculations using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculations using a, b and c...)

free (c);
cleanup_b:
free (b);
cleanup_a:
free (a);

my_end:
return error_code;


I'm not sure exactly how that improves portability?

My problem with this structure is that it does not clearly convey
that c is dependent on b and a, and that b is dependent on a. I
would rather have that relationship visually reinforced by nesting
even if it means marching halfway across the page, because then I
can see the relationship and its extent at a glance, instead of
groveling through the source.


I am a proponent of goto, in its place. This is not it. I would
code that snippet as:

int error_code = MEM_ERROR; /* default */

a = b = c = NULL;
if (a = malloc(sz_a)) {
...calculations using a...
if (b = malloc(sz_b)) {
...calculations using a and b...
if (c = malloc(sz_c)) {
...calculations using a, b and c...
error_code = NO_ERROR;
}
}
}
free (c);
free (b);
free (a);

and I would be more inclined to invert the selections to put the
good case at the end, assuming I don't need to calculate things
before the mallocs:

a = b = c = NULL;
if (!(a = malloc(...))) error(AFAILS);
else if (!(b = malloc(...))) error(BFAILS);
else if (!(c = malloc(...))) error(CFAILS);
else { /* we can go to work */
/* the real stuff goes here */
error(NOERROR); /* or some such */
}
free(c); free(b); free(a);

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 13 '05 #41

P: n/a

I am a proponent of goto, in its place. This is not it. I would
code that snippet as:

int error_code = MEM_ERROR; /* default */

a = b = c = NULL;
if (a = malloc(sz_a)) {
...calculations using a...
if (b = malloc(sz_b)) {
...calculations using a and b...
if (c = malloc(sz_c)) {
...calculations using a, b and c...
error_code = NO_ERROR;
}
}
}
free (c);
free (b);
free (a);

and I would be more inclined to invert the selections to put the
good case at the end, assuming I don't need to calculate things
before the mallocs:

a = b = c = NULL;
if (!(a = malloc(...))) error(AFAILS);
else if (!(b = malloc(...))) error(BFAILS);
else if (!(c = malloc(...))) error(CFAILS);
else { /* we can go to work */
/* the real stuff goes here */
error(NOERROR); /* or some such */
}
free(c); free(b); free(a);


I believe that both of these examples blow up if one of your allocs
fail. This is the problem the goto advocates are trying to solve.

NR

Nov 13 '05 #42

P: n/a
Noah Roberts wrote:
I believe that both of these examples blow up if one of your allocs
fail. This is the problem the goto advocates are trying to solve.


Nevermind, I always thought free(NULL) blew up. I stand corrected.

Both of your examples are much better than the goto stuff you responded
to. I also like the 2nd better than my own but I wrote mine under
mistaken assumptions :P

NR

Nov 13 '05 #43

P: n/a
In article <bl**********@quark.scn.rain.com>,
Noah Roberts <nr******@dontemailme.com> wrote:
a = b = c = NULL;
if (!(a = malloc(...))) error(AFAILS);
else if (!(b = malloc(...))) error(BFAILS);
else if (!(c = malloc(...))) error(CFAILS);
else { /* we can go to work */
/* the real stuff goes here */
error(NOERROR); /* or some such */
}
free(c); free(b); free(a);


I believe that both of these examples blow up if one of your allocs
fail. This is the problem the goto advocates are trying to solve.


I believe that if one or more of the malloc()'s fails, he'll end up
calling free(0) one or more times. I also believe that calling free(0)
is allowed and does nothing.

-- Brett
Nov 13 '05 #44

P: n/a
Noah Roberts wrote:
Noah Roberts wrote:
I believe that both of these examples blow up if one of your allocs
fail. This is the problem the goto advocates are trying to solve.


Nevermind, I always thought free(NULL) blew up. I stand corrected.

Both of your examples are much better than the goto stuff you responded
to. I also like the 2nd better than my own but I wrote mine under
mistaken assumptions :P


That's why I initialize the pointers to NULL. free(p), when p is
not initialized to either NULL or a value returned by malloc, will
blow up.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 13 '05 #45

P: n/a
"Arthur J. O'Dwyer" <aj*@nospam.andrew.cmu.edu> wrote...
Please don't post attachments to non-binaries groups.
A simple link to Google Groups, or, even better, a quick
reminder to "look three messages up the darn thread and
*read* it" would have sufficed.

And in general, don't use spaces in filenames. Some
uudecode clients might not even parse your attachment
correctly (I dunno what any RFC on the topic says; I'm
just pointing out the possibility).

-Arthur


Thanks for the tips! No that you have enhanced my knowledge of newsgroup
postings, I'll make every effort to refrain from doing it again.

Ridimz
Nov 13 '05 #46

P: n/a
On 01 Oct 2003 12:12:23 -0700, Micah Cowan <mi***@cowan.name> wrote:
Noah Roberts <nr******@dontemailme.com> writes: <snip>
while (always)
get input
if input is quit then die

do something
...

but it is much better do do ['structured' with boolean]

"Much better"... IYO. I frequently prefer the former, and call it
a "mid-test" loop. IMO, mainstream programming languages have
syntax for a pretest loop and posttest loop, but no one supports
the midtest loop. So I use the former example above, <snip>


Ada:
[<name>:] loop
<some stuff>;
exit [<name>] when <condition>;
<other stuff>;
end loop [<name>];
or
... for <var> in <range> loop ... similarly
... while <othercondition> loop ... similarly

LISP allows you to construct any syntax you like using macros, within
the normal parentheses and lexing rules. But I don't know if I would
count that as in the language, and mainstreamness is debatable.

Bourne-family shells allow multiple statements in the condition of a
while or until construct and only the "result" of the last is tested,
so the effect is the same although the syntax is less clear.
Although shell is debatably not a programming language at all.

FORTH does effectively the same thing, since it has no real statement
boundaries. Again not very mainstream.

- David.Thompson1 at worldnet.att.net
Nov 13 '05 #47

P: n/a
Micah Cowan <mi***@cowan.name> wrote in message news:<m3************@localhost.localdomain>...
Noah Roberts <nr******@dontemailme.com> writes:
Micah Cowan wrote:
Noah Roberts <nr******@dontemailme.com> writes:
>Sometimes it is better to break structure, but it
>always sacrifices maintainability and readability;
Not true. I frequently break structure for the explicit purpose
to improve portability. The typical case being something like:
int error_code = NO_ERROR;
a = malloc(sz_a);
if (a == NULL) { error_code = MEM_ERROR; goto my_end; }
(...calculations using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculations using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculations using a, b and c...)
free (c);
cleanup_b:
free (b);
cleanup_a:
free (a);
my_end:
return error_code;


<snipped>
How about this ;)

malloc(a...)
malloc(b...)
malloc(c...)

if (a && b && c) // or probably more readable to compare to null
explicetly...
do calcs...
else
clean up the mess // ie...if a free a, if b free b ...


That's all well and good: but what if you needed to use a before
you had the details on exactly what size you needed b to be?


ok then, how about this:
x = y = z = NULL;
if (x = malloc (a)) {
...
if (y = malloc (b)) {
...
if (z = malloc (c)) {
...
}
}
}

if (x) free (x);
if (y) free (y);
if (z) free (z);

much cleaner, plus structured as well (the indentation
indicates very clearly to me that successfull allocation
of x will allow allocation of y, which if successfull
will allow allocation of z).

if you need to *handle* the error at some point, then just
add in an integer to keep track of it

int error = 0;
x = y = z = NULL;
if (x = malloc (a)) {
...
if (y = malloc (b)) {
...
if (z = malloc (c)) {
...
} else error = 1;
} else error = 2;
} else error = 3;

if (x) free (x);
if (y) free (y);
if (z) free (z);

switch (error) {
case 1: printf ("no mem for z occurred\n"); break;
case 2: printf ("no mem for y occurred\n"); break;
case 3: printf ("no mem for x occurred\n"); break;
default: printf ("no error\n");
}
Nov 13 '05 #48

P: n/a
Noah Roberts <nr******@dontemailme.com> wrote in message news:<bl**********@quark.scn.rain.com>...

I am a proponent of goto, in its place. This is not it. I would
code that snippet as:

int error_code = MEM_ERROR; /* default */

a = b = c = NULL;
if (a = malloc(sz_a)) {
...calculations using a...
if (b = malloc(sz_b)) {
...calculations using a and b...
if (c = malloc(sz_c)) {
...calculations using a, b and c...
error_code = NO_ERROR;
}
}
}
free (c);
free (b);
free (a);

and I would be more inclined to invert the selections to put the
good case at the end, assuming I don't need to calculate things
before the mallocs:

a = b = c = NULL;
if (!(a = malloc(...))) error(AFAILS);
else if (!(b = malloc(...))) error(BFAILS);
else if (!(c = malloc(...))) error(CFAILS);
else { /* we can go to work */
/* the real stuff goes here */
error(NOERROR); /* or some such */
}
free(c); free(b); free(a);


I believe that both of these examples blow up if one of your allocs
fail. This is the problem the goto advocates are trying to solve.


where does it blow up ? what does it do wrong if the malloc fails ?

goose,
i must be dense today, or something like that :-)
Nov 13 '05 #49

P: n/a
goose wrote:
Noah Roberts <nr******@dontemailme.com> wrote in message news:<bl**********@quark.scn.rain.com>...

\

I believe that both of these examples blow up if one of your allocs
fail. This is the problem the goto advocates are trying to solve.

where does it blow up ? what does it do wrong if the malloc fails ?

goose,
i must be dense today, or something like that :-)


You are just comming in late to a thread and didn't read the whole thing.

NR

Nov 13 '05 #50

52 Replies

This discussion thread is closed

Replies have been disabled for this discussion.