473,836 Members | 1,333 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

for(;;) or while(1)?

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
52 21990
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
Chris Dollin wrote:
Noah Roberts wrote:
.... snip ...
N-and-a-half loops are just as structured as N loops. The idiom

while (yourChoiceForT rue)
{ 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 (yourChoiceForT rue) {
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(pream bleparams)) {
postamble;
}

--
Chuck F (cb********@yah oo.com) (cb********@wor ldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home .att.net> USE worldnet address!
Nov 13 '05 #32
Noah Roberts <nr******@donte mailme.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; }
(...calculation s using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculation s using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculation s 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
"Mike Wahler" <mk******@mkwah ler.net> wrote in message news:<qY******* ***********@new sread3.news.pas .earthlink.net> ...
"Minti" <mi************ @yahoo.com> wrote in message
news:e8******** *************** ***@posting.goo gle.com...
"Mike Wahler" <mk******@mkwah ler.net> wrote in message

news:<PZ******* **********@news read4.news.pas. earthlink.net>. ..
"Rick" <rrquick@nosp am-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
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
Micah Cowan wrote:
Noah Roberts <nr******@donte mailme.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; }
(...calculation s using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculation s using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculation s 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
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
Noah Roberts <nr******@donte mailme.com> writes:
Micah Cowan wrote:
Noah Roberts <nr******@donte mailme.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; }
(...calculation s using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculation s using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculation s 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 "readabilit y" 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
Micah Cowan <mi***@cowan.na me> 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; }
(...calculation s using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculation s using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculation s 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
On Thu, 02 Oct 2003 17:01:42 -0700, John Bode wrote:
Micah Cowan <mi***@cowan.na me> 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; }
(...calculation s using a...)
b = malloc(sz_b);
if (b == NUL) { error_code = MEM_ERROR; goto cleanup_a; }
(...calculation s using a and b...)
c = malloc(sz_c);
if (c == NUL) { error_code = MEM_ERROR; goto cleanup_b };
(...calculation s 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_ret urn;

mem_error:
error_code = MEM_ERROR;
goto cleanup_and_ret urn;

file_error:
error_code = FILE_ERROR;
goto cleanup_and_ret urn;

cleanup_and_ret urn:
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

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

24
2721
by: Andrew Koenig | last post by:
PEP 315 suggests that a statement such as do: x = foo() while x != 0: bar(x) be equivalent to while True:
36
2818
by: invni | last post by:
I have a nested while. How do I go from the inner while to the beginning of the outer while? Can this be done without using goto? while_1() { some codes here while_2() { if true go to the beginning of while_1 }
5
2330
by: Tom Kent | last post by:
I'm running into a weird circumstance with Visual Studio 7.1, where it will not properly indent a while loop nested inside a do-while loop. It compiles and runs fine, but the automatic indenting messes it up every time. Here's an example: using System; namespace Do_While_Test {
6
71985
by: John Pass | last post by:
What is the difference between a While and Do While/Loop repetition structure. If they is no difference (as it seems) why do both exist?
12
1987
by: Howard | last post by:
Hello everyone (total VB.NET beginner here), I'm reading the "SAMS Teach Yourself VB.NET In 21 Days" book, and came across an exercise that I can't get to work. The exercise asks that you create a game that makes the user guess a number from 1-100, and you tell the user "lower" or "higher" as they input their guesses, until they guess the correct number, at which point you then tell the user "Correct". I tried using the While Loop, and...
7
3200
by: DaVinci | last post by:
I am writing a pong game.but met some problem. the ball function to control the scrolling ball, void ball(int starty,int startx) { int di ,i; int dj,j; di = 1; dj = 1; i = starty;
5
12250
by: é›· | last post by:
suggest add do while loop in later version
3
1856
by: libsfan01 | last post by:
hi all in my js code i have a while loop contained within a while loop executed on the basis of a conditional if statement, what i want to do is end the entire function on the last execution on the 2nd while loop (contained within the 1st), bcos the 2nd while loop changes the condition evaluated by the if statement which means another while loop (executed where if evaluates differently) gets executed straight afterwards
10
2095
by: wd.jonsson | last post by:
Hmm, my while loop with "or" doesn't seem to work as I want it to... How do I tell the while loop to only accept "Y" or "y" or "N" or "n" input from the str(raw_input)? Thank's in advance! Snippet of code: import os
11
2733
by: nembo kid | last post by:
If i>0 the while loop is executed; if i==0 not. Ok, but also if i<0 the while loop is executed. So, which are the rules? Which values must assume the "test condition" to be assumed like true o false? Thanks in advance #include <stdio.h>
0
9665
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10835
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10249
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
9367
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
7785
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5645
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5818
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4447
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
4007
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.