[net.lang.c] Infinite loops

badri@ur-helheim.UUCP (Badri Lokanathan) (04/15/86)

This is really a nitpicking question, but, anyway!
There are several ways of creating infinite loops:
while(1) {
   .
   .
   .
   }

Or
for(;;) {
   .
   .
   .
   }

And others too. My question is the following: is there any reason (other
than personal preferance) why one would prefer to use any particular form?
I personally prefer the while(1) form since it seems to make better reading.
Even better, I sometimes define TRUE to be 1 and then use while(TRUE).

chris@umcp-cs.UUCP (Chris Torek) (04/17/86)

In article <577@ur-helheim.UUCP> badri@ur-helheim.UUCP
(Badri Lokanathan) writes:
>There are several ways of creating infinite loops:

Namely, `while (1)' and `for (;;)'.  (There are others, but these
seem to be the nominal standard.)

>... is there any reason (other than personal preferance) why one
>would prefer to use any particular form?

Some compilers generate a `test the constant 1' for the former
sequence, and no test for the latter; but I imagine that by now
this is rather rare.

>I personally prefer the while(1) form since it seems to make better reading.

Oddly enough, I prefer the other form, but for the same reason.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1415)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

badri@ur-helheim.UUCP (Badri Lokanathan) (04/17/86)

The question asked was 
Is there any "preferred way" to create infinite loops ?
Thanks to all those who sent me mail. For those who are curious,
Chris Torek's article <961@umcp-cs.UUCP> discusses the issue in
some detail.

bet@ecsvax.UUCP (Bennett E. Todd III) (04/18/86)

I've always been fond of:

	...
	#define EVER ;;
	...
		for (EVER) {
	...

I know, it's terminally "cute".
-Bennett
-- 

Bennett Todd -- Duke Computation Center, Durham, NC 27706-7756; (919) 684-3695
UUCP: ...{decvax,seismo,philabs,ihnp4,akgua}!mcnc!ecsvax!duccpc!bet

aglew@ccvaxa.UUCP (04/19/86)

while(1){} vs. for(;;)

you forgot to mention do{}while(1);

take a look at the code your compiler produces for each one. a good
optimizing compiler should make them all the same, but not all compilers are
good optimizing compilers. i fell into the habit of using while(1) on
68000s; when i started working on 80x86s i found that for(;;) was faster.
i have therefore put

#if defined(MPU68000)
#   define loop while(1)
#elif defined(MPU8086) || defined(MPU80286)
#   define loop for(;;)
#endif

into my personal header. if do{}while(1) proved faster then I suppose I
would have to put an endloop in.

My favorites are

#define the_sky_is_blue 1
while(the_sky_is_blue){}

and

#define ever_and_a_day ;;
for(ever_and_a_day){}

or, in Pascal

CONST Hell_freezes_over = TRUE;
REPEAT ... UNTIL Hell_freezes_over;

But my boss gets angry enough at me as it is! (are you there, Gary?)

Andy "Krazy" Glew. Gould CSD-Urbana.    USEnet:  ihnp4!uiucdcs!ccvaxa!aglew
1101 E. University, Urbana, IL 61801    ARPAnet: aglew@gswd-vms

gwyn@BRL.ARPA (04/19/86)

do ... while(1);

while(1) ...

for(;;) ...

are all widely-used idioms for unconditional looping in C.
I personally prefer the latter, but the choice is just a
matter of taste.  Any reasonable compiler will generate
efficient code for all three constructs.

LINNDR%VUENGVAX.BITNET@wiscvm.ARPA (04/19/86)

badri@ur-helheim.uucp asks about infinite loops and what other people
do to get them. He advocates

#define TRUE 1

        while (TRUE)

I'd liked to suggest another alternative to those who may not have seen it.

#define EVER ;;

        for (EVER)

David Linn
----------------------------------------------------------
BITNET:         LINNDR@VUEngVAX.BITNET or PEARL@VANDVMS1.BITNET
MAILNET:        LINN_D_R    \
                David_R_Linn >@VANDERBILT.MAILNET
                David_Linn  /
CSNET:          drl@vanderbilt.csnet
SnailMail:      P.O. 3241-B Vanderbilt
                Nashville, TN   37235

roe@toram.UUCP (Roe Peterson) (04/21/86)

In article <577@ur-helheim.UUCP> badri@ur-helheim.UUCP (Badri Lokanathan) writes:
>My question is the following: is there any reason (other
>than personal preferance) why one would prefer to use any particular form?
>I personally prefer the while(1) form since it seems to make better reading.
>Even better, I sometimes define TRUE to be 1 and then use while(TRUE).

Unless you have a very unique optimizer, it is usually better to use the
for(;;) form rather than the while(1) form.  Reason is:  while(1) is
ALWAYS evaluated (ie. : is 1 TRUE? if so, continue) before each iteration,
whereas for(;;) compiles as a simple branch or jump instruction with no
test and no conditional branch.

simply loops with no checks.


-- 

				Roe Peterson
				{linus,ihnp4,decvax}!utzoo!toram!roe

				All that glitters is spray-paint.

grr@cbmvax.cbm.UUCP (George Robbins) (04/21/86)

In article <117@brl-smoke.ARPA> gwyn@BRL.ARPA (VLD/VMB) writes:
>
>do ... while(1);
>while(1) ...
>for(;;) ...
>
>are all widely-used idioms for unconditional looping in C.
>I personally prefer the latter, but the choice is just a
>matter of taste.  Any reasonable compiler will generate
>efficient code for all three constructs.

#define loop for(;;)

This is a clean way to do it, but be aware that there is no obvious stopping
point, and soon C purists will soon be declaring that your code has been tainted
by exposure to noxious influences from Algol 68 or worse...

-- 
George Robbins - now working with,	uucp: {ihnp4|seismo|caip}!cbmvax!grr
but no way officially representing	arpa: cbmvax!grr@seismo.css.GOV
Commodore, Engineering Department	fone: 215-431-9255 (only by moonlite)

franka@mmintl.UUCP (Frank Adams) (04/22/86)

In article <1444@ecsvax.UUCP> bet@ecsvax.UUCP (Bennett E. Todd III) writes:
>	#define EVER ;;
>	...
>		for (EVER) {
>	...
>
>I know, it's terminally "cute".

No, no, no.  It's INterminally cute.

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Multimate International    52 Oakland Ave North    E. Hartford, CT 06108

david@ztivax.UUCP (04/22/86)

Another terminally cute infinite loop which was used in ratfor:

repeat {
	...
} until (hell_freezes_over)

herndon@umn-cs (04/25/86)

  For the infinite loop, I like the sequence

#define ever ;;

...

   for(ever) {
        ...
   }

				Robert Herndon

Unknown@ur-helhe (04/25/86)

This message is empty.

steiny@scc (04/26/86)

**

	This loop looked strange to me, but I felt kind of silly
when I realized that it is perfectly good C.


	main()
	{
		main();
	}

It loops until it overflows the stack.
-- 
scc!steiny
Don Steiny @ Don Steiny Software 
109 Torrey Pine Terrace
Santa Cruz, Calif. 95060
(408) 425-0382

ARPA@brl-smoke (04/28/86)

Actually, any decent C compiler will optimize away "while(1)",
so that it will be no less efficient than "for(;;)".

tim@ism780c (04/29/86)

In article <1299@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes:
>
>No, no, no.  It's INterminally cute.
		   ^^^^^^

By the way, INterm is a trademark of Interactive Systems Corporation.
The above should be
				TM
	No, no, no.  It's INterm  inally cute.

Thank you. :-)
-- 
Tim Smith       sdcrdcf!ism780c!tim || ima!ism780!tim || ihnp4!cithep!tim

ron@brl-sem (04/30/86)

> Unless you have a very unique optimizer, it is usually better to use the
> for(;;) form rather than the while(1) form.  Reason is:  while(1) is
> ALWAYS evaluated (ie. : is 1 TRUE? if so, continue) before each iteration,
> whereas for(;;) compiles as a simple branch or jump instruction with no
> test and no conditional branch.
> 
Crapola.  All the PCC impementations I've checked don't test the constant
even when you don't turn the optimizer on.  Our old PDP-11 Ritchie compiler
does generate the test, but the standard -O optimizer removes it.  Nothing
unique here.

-Ron

levy@ttrdc (04/30/86)

In article <140@toram.UUCP>, roe@toram.UUCP writes:
>In article <577@ur-helheim.UUCP> badri@ur-helheim.UUCP (Badri Lokanathan) writes:
>>My question is the following: is there any reason (other
>>than personal preferance) why one would prefer to use any particular form?
>>I personally prefer the while(1) form since it seems to make better reading.
>>Even better, I sometimes define TRUE to be 1 and then use while(TRUE).
>Unless you have a very unique optimizer, it is usually better to use the
>for(;;) form rather than the while(1) form.  Reason is:  while(1) is
>ALWAYS evaluated (ie. : is 1 TRUE? if so, continue) before each iteration,
>whereas for(;;) compiles as a simple branch or jump instruction with no
>test and no conditional branch.
>				Roe Peterson

What very unique optimizer?  Here's what I get (SysV 3B20, cc -S [note no -O]):

$ cat > while1.c
main()	/* while1.c */
{
	register int a=0;
	while (1) a++;
}
^D$ cc -S while1.c
$ cat while1.s
	.file	"while1.c"
	.data
	.text
	.align	4
	.def	main;	.val	main;	.scl	2;	.type	044;	.endef
	.globl	main
main:
	save	&.R1
	addw2	&.F1,%sp
	movw	&0,%r8
.L14:
	addw2	&1,%r8
	jmp	.L14
	^^^^^^^^^^^^
.L13:
.L12:
	ret	&.R1
	.set	.R1,1
	.set	.F1,0
	.def	main;	.val	.;	.scl	-1;	.endef
	.data
$ cc -c while1.s
$ dis while1.o
		****   DISASSEMBLER  ****


disassembly for while1.o

section	.text
main()
	   0:  7a10                          save    &0x1,&0x0
	   2:  346c 0000 0000 000b           addw2   &0x00000,%sp
	   a:  1508                          movw    &0x0,%r8
	   c:  1118                          addw2   &0x1,%r8
	   e:  9002                          br      -0x2 <c>
					     ^^^^^^^^^^^^^^^^
	  10:  7b10                          ret     &0x1
	  12:  dede                          nop     
-- 
 -------------------------------    Disclaimer:  The views contained herein are
|       dan levy | yvel nad      |  my own and are not at all those of my em-
|         an engihacker @        |  ployer or the administrator of any computer
| at&t computer systems division |  upon which I may hack.
|        skokie, illinois        |
 --------------------------------   Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
						vax135}!ttrdc!levy

gwyn@brl-smoke (04/30/86)

In article <2061@ism780c.UUCP> tim@ism780c.UUCP (Tim Smith) writes:
>In article <1299@mmintl.UUCP> franka@mmintl.UUCP (Frank Adams) writes:
>>No, no, no.  It's INterminally cute.
>By the way, INterm is a trademark of Interactive Systems Corporation.
>The above should be
>				TM
>	No, no, no.  It's INterm  inally cute.

Isn't "TM" a trademark of Maharish Yogi or some such?
            ...
          TM
        TM
      TM
INterm         inally cute.

(Not exactly a loop, but at least it's infinite.  Is it also transcendental?)

jsdy@hadron.UUCP (Joseph S. D. Yao) (05/03/86)

In article <117@brl-smoke.ARPA> gwyn@BRL.ARPA (VLD/VMB) writes:
>do ... while(1);
>while(1) ...
>for(;;) ...
>are all widely-used idioms for unconditional looping in C.
>I personally prefer the latter, but the choice is just a
>matter of taste.  Any reasonable compiler will generate
>efficient code for all three constructs.

Unfortunately, as I'm sure many readers of this group will agree,
not all compilers are reasonable.  The only one that consistently
doesn't generate useless code is for (;;) {...}.

BTW, given all these defines:  here are some "cute" ones of mine:

#define ever	(;;)	/* for ever ...; */
#define unless(x)	if (!(x))	/* unless (x) ...; */
#define until(x)	while (!(x))	/* until (x) ...;
					   do ... until (x); */

and of course	[ given #define OK 0 ]

#define streq(a,b)	(strcmp(a, b) == OK)
#define strneq(a,b,n)	(strncmp(a, b, n) == OK)
-- 

	Joe Yao		hadron!jsdy@seismo.{CSS.GOV,ARPA,UUCP}

ron@brl-sem.ARPA (Ron Natalie <ron>) (05/04/86)

In article <390@hadron.UUCP>, jsdy@hadron.UUCP (Joseph S. D. Yao) writes:
> 
> Unfortunately, as I'm sure many readers of this group will agree,
> not all compilers are reasonable.  The only one that consistently
> doesn't generate useless code is for (;;) {...}.
Joe, it is exactly this second guessing of compilers that get people in
trouble.  It is bad to make sweeping statements as to what is more efficient
because some compilers just do entirely unexpected, yet no more inefficient
things with code generation.

But the truth of the matter is, the PCC implementations get it right without
any optimization whatsoever.  Since most UNIX's use PCC as the base for their
C compilers, that generally solves the problem.
The original Ritchie compiler does miss it in the code generation, but the
optimzer removes the silly test.

Wait until the compiler comes out that does the following:

	for(;;)  { included code )

	L1:	NOP	/  init
	L2:	NOP	/  test
		INCLUDED CODE
		NOP	/  increment
		JUMP	L2

Frankly, if your compiler is so bad that it can't perform routine constant
elimination, than I doubt that you will really notice the extra performance
loss.  It's probably still multiplying out 60*60 for seconds in an hour
and other definitions.

-Ron

kwh@bentley.UUCP (KW Heuer) (05/06/86)

In article <390@hadron.UUCP> hadron!jsdy (Joseph S. D. Yao) writes:
>BTW, given all these defines:  here are some "cute" ones of mine: ...
>#define streq(a,b)     (strcmp(a, b) == OK)

A more general mechanism is
#define strrel(a,R,b)	(strcmp(a, b) R 0)
which allows you to write strrel(a,==,b).  Some consider this to be abuse
of the preprocessor.

greg@utcsri.UUCP (Gregory Smith) (05/06/86)

In article <203@brl-sem.ARPA> ron@brl-sem.ARPA (Ron Natalie <ron>) writes:
>In article <390@hadron.UUCP>, jsdy@hadron.UUCP (Joseph S. D. Yao) writes:
>> 
>> Unfortunately, as I'm sure many readers of this group will agree,
>> not all compilers are reasonable.  The only one that consistently
>> doesn't generate useless code is for (;;) {...}.
>Joe, it is exactly this second guessing of compilers that get people in
>trouble.  It is bad to make sweeping statements as to what is more efficient
>because some compilers just do entirely unexpected, yet no more inefficient
>things with code generation.
...
>Wait until the compiler comes out that does the following:
>
>	for(;;)  { included code )
>
>	L1:	NOP	/  init
>	L2:	NOP	/  test
>		INCLUDED CODE
>		NOP	/  increment
>		JUMP	L2
>

Well, it's even worse... Consider C/80, a subset C compiler for 8080's
[ no floats, longs, structs, unions, **s, :-( ]:

	for( e1;e2; e3 ){
becomes
		<e1>
	f0:	<e2>
		JZ	f3
		JMP	f2
	f1:	<e3>
		JMP	f0
	f2:	<loop code>
		JMP	f1
	f3:

So for(;;) just reduces to

	f0:	JMP	f2
	f1:	JMP	f0
	f2:	<loop code>
		JMP	f1

Really! The compiler apparently cannot save <e3> until later; it doesn't
build trees. It also pushes function args left-to-right ( another story ).

while(1), on the other hand, becomes

	w0:	LXI	H,1	; evaluate 1 ( in 16-bit reg HL )
		MOV	A,H	; test HL by ORing the upper
		ORA	L	;	and lower bytes to the ACC
		JZ	w1	;	( standard 8080 idiom )
		<loop>
		JMP	w0
	w1:

>Frankly, if your compiler is so bad that it can't perform routine constant
>elimination, than I doubt that you will really notice the extra performance
>loss.  It's probably still multiplying out 60*60 for seconds in an hour
>and other definitions.

C/80 is ( using a 'mult' subroutine, of course. a<b uses a 'lt' subroutine ).

I have written a large amount of code with this beast - including an
`optimizing assembler' to cure many of the horridities emitted by the
compiler.

Sorry, I know, this should be in net.lang.brain.damaged. If you don't
flame me, I promise never to mention this compiler again :-).

P.S. There is an 8088 version of the compiler - I don't know if it is
any better ( or worse ).

-- 
"Canabee be said2b or not2b anin tire b, if half thabee isnotabee, due2
somain chunt injury?" - Eric's Dilemma
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg

davidsen@steinmetz.UUCP (Davidsen) (05/06/86)

In article <116@cbmvax.cbmvax.cbm.UUCP> grr@cbmvax.UUCP (George Robbins) writes:
>In article <117@brl-smoke.ARPA> gwyn@BRL.ARPA (VLD/VMB) writes:
>>
>>do ... while(1);
>>while(1) ...
>>for(;;) ...
>>
>>are all widely-used idioms for unconditional looping in C.
>>I personally prefer the latter, but the choice is just a
>>matter of taste.  Any reasonable compiler will generate
>>efficient code for all three constructs.
>
>#define loop for(;;)
>
>This is a clean way to do it, but be aware that there is no obvious stopping
>point, and soon C purists will soon be declaring that your code has been tainted
>by exposure to noxious influences from Algol 68 or worse...
>

You could change the definition(s) to:
  #define loop for(;;){
  #define endloop }

Or, as I have seen in a few programs:
  #define ever (;;)
-- 
	-bill davidsen

	seismo!rochester!steinmetz!--\
       /                               \
ihnp4!              unirot ------------->---> crdos1!davidsen
       \                               /
        chinet! ---------------------/        (davidsen@ge-crd.ARPA)

"Stupidity, like virtue, is its own reward"

ado@elsie.UUCP (Arthur David Olson) (05/07/86)

> . . .All the PCC impementations I've checked don't test the ["1" in a
> "while (1)"] even when you don't turn the optimizer on.  Our old PDP-11
> Ritchie compiler does generate the test, but the standard -O optimizer
> removes it. . .

If I recall my ancient history aright, the Version 6 C compiler generated the
constant test, and the Version 6 optimizer failed to remove it.
--
PDP is a Digital Equipment Corporation trademark.
--
	UUCP: ..decvax!seismo!elsie!ado		ARPA: elsie!ado@seismo.ARPA
	DEC, VAX, Elsie & Ado are Digital, Borden & Shakespeare trademarks.

keesan@bbncc5.UUCP (Morris M. Keesan) (05/20/86)

In article <6091@elsie.UUCP> ado@elsie.UUCP (Arthur David Olson) writes:
>If I recall my ancient history aright, the Version 6 C compiler generated the
>constant test, and the Version 6 optimizer failed to remove it.

The C compiler I was using on a PDP 11-70 V6 system not only generated a test
for "while(1)", it issued a warning!  ("Warning -- test for constant", or
some such).  I don't know if this was a standard feature of the V6 compiler or 
merely a local aberration.  I remember complaining to someone that if the
compiler was clever enough to notice the constant it should be clever enough
to avoid generating the test, and he defended the compiler's action by claiming
that the proper idiomatic expression was "for(;;)".  It's because of that
compiler that I still tend to write "for(;;)", even though "while(1)" seems
more intuitive to me.
-- 
Morris M. Keesan
keesan@bbn-unix.ARPA
{decvax,ihnp4,etc.}!bbncca!keesan