[net.lang.c] condition convention 'if

gam@amdahl.UUCP (G A Moffett) (04/27/85)

> To prevent silly mistakes like 
> 	if (j = 10)
> I usually write
> 	if (10 == j)
> By putting the constant first, I ensure that the compiler will catch the 
> typo.

I think this is a good idea.  Any criticisms?  The only problem
I have with it is that I am not accustomed to reading code written
this way.
-- 
Gordon A. Moffett               ...!{ihnp4,cbosgd,sun}!amdahl!gam

shannon@sun.uucp (Bill Shannon) (04/27/85)

> > To prevent silly mistakes like 
> > 	if (j = 10)
> > I usually write
> > 	if (10 == j)
> > By putting the constant first, I ensure that the compiler will catch the 
> > typo.
> 
> I think this is a good idea.  Any criticisms?  The only problem
> I have with it is that I am not accustomed to reading code written
> this way.
> -- 
> Gordon A. Moffett               ...!{ihnp4,cbosgd,sun}!amdahl!gam

What do you mean, any criticisms?  This is one of the most ugly
perversions of C I've ever seen!  I tend to read this in terms of
"if variable equals constant" and try to figure out how the value
"10" is ever going to change!  YUCK YUCK YUCK!!!!

People that write "if (10 == j)" probably also write "while (1)".
What do you mean, "while 1"???  Are you expecting "1" to change???
Everyone knows this should be written "for (;;)", read "forever".

					Bill Shannon

dupuy@columbia.UUCP (Alex Dupuy) (04/28/85)

In article <2140@sun.uucp> shannon@sun.uucp (Bill Shannon) writes:
> > > To prevent silly mistakes like 
> > >	if (j = 10)
> > > I usually write
> > >	if (10 == j)
> > > By putting the constant first, I ensure that the compiler will catch the 
> > > typo.
> >  
> 
> [Flames...]
> 
> People that write "if (10 == j)" probably also write "while (1)".
> What do you mean, "while 1"???  Are you expecting "1" to change???
> Everyone knows this should be written "for (;;)", read "forever".
> 
>					Bill Shannon

I agree that "if (10 == j)" looks ridiculous, but to prevent ridiculous errors
like
	 "if (j = 10)"			    /* j is set to 10 */
 or
	 "if (j != NULL & j->next != NULL)" /* bitwise AND evaluates j _and_
					       j->next even if j is nil  */

and to make my code more human readable (:-) I use the following #definitions:

#define and	&&
#define or	||
#define is	==
#define isnt	!=
#define not	!

As a result, my code looks like

	 "if (j is 10)" 
	 "if (j isnt NULL and j->next isnt NULL)"

which even Pascal types (like me) can read.  And there is *no* way to make
those silly mistakes shown above.  I even throw in another:

#define ever	;;

so I can have *real* "for (ever)" loops.

						Alexander Dupuy

Ok, go ahead and flame me for not being a strict K&R type who likes C to
look like a mess of proofreaders marks (and if you think this isn't 
"heretical" enough, you should see my indentation style :-).

herbison@ultra.DEC (B.J.) (04/28/85)

> What do you mean, any criticisms?  This is one of the most ugly
> perversions of C I've ever seen!  I tend to read this in terms of
> "if variable equals constant" and try to figure out how the value
> "10" is ever going to change!  YUCK YUCK YUCK!!!!
> 
> People that write "if (10 == j)" probably also write "while (1)".
> What do you mean, "while 1"???  Are you expecting "1" to change???
> Everyone knows this should be written "for (;;)", read "forever".
> 
> 					Bill Shannon

I am glad that this discussion has been kept civil and that you restrained
from using emotional or personal attacks.  We wouldn't want net.lang.c to
be confused with net.flame or net.abortion.  Tell me Bill, is that how you
respond whenever someone makes a comment you don't agree with -- yelling
"YUCK YUCK YUCK" in their face?  I'm glad I don't work with you.

Personally, I don't like "while (1)", I much prefer "while (TRUE)",
just so it is obvious what is going on.
A much better solution, which explicitly says what is happening, is
    #define loop_forever <insert your favorite idiom here>

But back to the original topic.  "one of most ugly perversions of C"--
I tend to only use language this strong for things like the fact that
"=" is the assignment operator in C rather than a test for equality.
I am used to it, but it was a bad mistake and has cost thousands of
people tens of thousands of wasted hours in looking for the bugs it
has caused.  Using 'if (CONSTANT == j)...' [avoid putting magic numbers
in code, that can cause bugs also] seems like a way to help solve
problems.

In the meantime, try to avoid using code like 'if ((i+1) == (2*j))...',
some people (by their own admission) might not be able to handle a
comparison where neither side is a variable and neither side is a constant.

						B.J.
                                                Herbison%Ultra.DEC@decwrl.ARPA

brooks@lll-crg.ARPA (Eugene D. Brooks III) (04/29/85)

> What do you mean, any criticisms?  This is one of the most ugly
> perversions of C I've ever seen!  I tend to read this in terms of
> "if variable equals constant" and try to figure out how the value
> "10" is ever going to change!  YUCK YUCK YUCK!!!!
> 
> People that write "if (10 == j)" probably also write "while (1)".
> What do you mean, "while 1"???  Are you expecting "1" to change???
> Everyone knows this should be written "for (;;)", read "forever".
> 
> 					Bill Shannon

I will agree with a claim that (10 == j) is not very pleasing to the eye
when you first see it.  To claim that it is a perversion of C is going a
little too far.  It legal C and usage has a definite purpose for the error
prone.  To then claim that while(1) is wrong and that the proper way to do
the same thing is for(;;) is going even further.  Beauty is in the eye of
the beholder.  I understand what is being done with while(1), the compiler
understands what is being done with while(1), even YOU understand what is
being done with while(1).  Hence its good C and does not deserve to be called
wrong.  For(;;) is not quite as clear to me and I would have to check the
manual first.

So lets cool the flame on a good suggestions that have the origin in the
solution for a problem that bites many.

ggs@ulysses.UUCP (Griff Smith) (04/29/85)

> > To prevent silly mistakes like 
> > 	if (j = 10)
> > I usually write
> > 	if (10 == j)
> > By putting the constant first, I ensure that the compiler will catch the 
> > typo.
> 
> I think this is a good idea.  Any criticisms?  The only problem
> I have with it is that I am not accustomed to reading code written
> this way.
> -- 
> Gordon A. Moffett               ...!{ihnp4,cbosgd,sun}!amdahl!gam

Don't get me wrong, I also think the idea has some charm, but it's not as
innocent a change as it appears to be.  I recently found a bug in a C
compiler: if (j == 0.0) worked, if (0.0 == j) didn't.  It seems the
implementors wanted to avoid creating double precision constant zeros,
so they planned a two-step optimization where

L1:	.long	0x00000000, 0x00000000
	.text
	cmpd2	4(fp),L1

would be reduced to

	cmpd2	4(fp),$0

and then further reduced to

	tstl	4(fp)

Unfortunately, they forgot that "cmpd2 $0,j" doesn't fit the pattern;
the intermediate code pattern escaped to the final output.  Since $0
was not a legal representation of a floating point number (this was not
a VAX), the assembler screamed about an illegal address and sulked.
The compiler had apparently never encountered this case in any of the
UNIX(TM) System source.

The point of all this is: if you want to use unusual conventions, be
prepared to evade bugs in compilers designed for those who are less
imaginative.  Also be prepared to defend against flames from people
who find it hard to read your code.
-- 

Griff Smith	AT&T Bell Laboratories, Murray Hill
Phone:		(201) 582-7736
Internet:	ggs@ulysses.uucp
UUCP:		ulysses!ggs  ( {allegra|ihnp4}!ulysses!ggs )

hkr4627@acf4.UUCP (Hedley K. J. Rainnie) (04/29/85)

if(constant == expr) ... is ugly. BUT I take offence to while(1) being called
ugly. 

Hedley.

peters@cubsvax.UUCP (Peter S. Shenkin) (04/29/85)

>> To prevent silly mistakes like 
>> 	if (j = 10)
>> I usually write
>> 	if (10 == j)
>> By putting the constant first, I ensure that the compiler will catch the 
>> typo.
>
>I think this is a good idea.  Any criticisms?  The only problem
>I have with it is that I am not accustomed to reading code written
>this way.
>-- 
>Gordon A. Moffett               ...!{ihnp4,cbosgd,sun}!amdahl!gam

Just that instead of writing, in the traditional manner,
	if(pc=malloc(nbytes)==NULL)...
you have to insert extra parens if you use the other form:
	if(NULL==(pc=malloc(nbytes)))..
This is because == has higher precedence than =, and the expression will
first evaluate NULL==pc, then try to set the resulting constant to whatever 
malloc() returns (except, of course, the compiler doesn't let you get that far).

I used to use the (NULL==var form but reverted to the more traditional
form because the extra parens kept making me do a double-take.
I'd rather skip the parens and always put the constant at the end. That way
I always know where to look for it.  You pays your money & takes your choice.
If it weren't for this problem, though, I'd use the proposed form.

Peter S. Shenkin,  Biology, Columbia Univ.   cubsvax!peters

oacb2@ut-ngp.UUCP (oacb2) (04/29/85)

> Just that instead of writing, in the traditional manner,
>	if(pc=malloc(nbytes)==NULL)...
> you have to insert extra parens if you use the other form:
>	if(NULL==(pc=malloc(nbytes)))..

Huh???  The first sets pc to 0 or 1 depending on whether the result of
malloc is or is not NULL.  The second sets pc to the result of malloc.

This seems to be another argument in favor of (CONSTANT == expression).
The first is probably incorrect, but legal C.

I think the (CONSTANT == expression) form is ugly.  That may just be that
it's not very familiar (guess it's been too many years since I used APL).
It does seem to have some merit though.
-- 

	Mike Rubenstein, OACB, UT Medical Branch, Galveston TX 77550

lspirkov@udenva.UUCP (Goldilocks) (04/29/85)

In article <> gam@amdahl.UUCP (G A Moffett) writes:
>> To prevent silly mistakes like 
>> 	if (j = 10)
>> I usually write
>> 	if (10 == j)
>> By putting the constant first, I ensure that the compiler will catch the 
>> typo.
>
>I think this is a good idea.  Any criticisms?  The only problem
>I have with it is that I am not accustomed to reading code written
>this way.
>-- 
>Gordon A. Moffett

yeah, it does seem very odd to ask if 10 equals something else.
after all, 10 == 10 and nothing else.  j is the variable.
it's easy to think the other way around.

i have a friend that uses macros to avoid the silly mistake.
instead of saying
	if (j == 10)
he defines a macro IS and says
	if (j IS 10). 
-- 

					Goldi

email:  udenva!lspirkov

alexis@reed.UUCP (Alexis Dimitriadis) (04/30/85)

>> > To prevent silly mistakes like 
>> > 	if (j = 10)
>> > I usually write
>> > 	if (10 == j)
>> > By putting the constant first, I ensure that the compiler will catch the 
>> > typo.
>> 
>> I think this is a good idea.  Any criticisms?  The only problem
>> I have with it is that I am not accustomed to reading code written
>> this way.

>What do you mean, any criticisms?  This is one of the most ugly
>perversions of C I've ever seen!  

  I think it is a great idea.  Congratulations to the original
poster for coming up with a construction that underscores the distinction
between assignment and comparison, (the left side of an assignment must
be an lvalue), while still being legal C, simple, no harder to write,
and easy to understand.  

  If it wasn't done this way to date, it is surely a historical
accident.  To use the common example, I am sure the construction `a += 5'
seemed ugly to the C programmers of yore, but it is now standard
practice.  (With a little help from the dictatorial compiler writers, of
course).

>I tend to read this in terms of
>"if variable equals constant" and try to figure out how the value
>"10" is ever going to change!  YUCK YUCK YUCK!!!!

  If you expect j to change when you read `if (j == 10)', then you are
sorely in need of ways to differentiate between assignment and
comparison!!!

>People that write "if (10 == j)" probably also write "while (1)".
>What do you mean, "while 1"???  Are you expecting "1" to change???
>Everyone knows this should be written "for (;;)", read "forever".

  What, are you expecting "" to change when you write `for (;;)'? (:-)
The for loop chould be preferred since it is the standard idiom, but
there are GOOD reasons to use (constant == lvalue).  (Would you argue
against do ... while loops simply because while loops are more common?)

Respectfully,
 Alexis Dimitriadis
-- 
_______________________________________________
  As soon as I get a regular job, the opinions expressed above
will attach themselves to my employer, who will never be rid of
them again.

	  alexis @ reed
	...ihnp4!{harvard|tektronix}!reed
	...decvax!tektronix!reed
	...teneron!reed

peters@cubsvax.UUCP (Peter S. Shenkin) (04/30/85)

In article <> oacb2@ut-ngp.UUCP writes:
>> Just that instead of writing, in the traditional manner,
>>	if(pc=malloc(nbytes)==NULL)...
>> you have to insert extra parens if you use the other form:
>>	if(NULL==(pc=malloc(nbytes)))..
>
>Huh???  The first sets pc to 0 or 1 depending on whether the result of
>malloc is or is not NULL.  The second sets pc to the result of malloc.
>
>	Mike Rubenstein, OACB, UT Medical Branch, Galveston TX 77550

As the contributor of this chestnut ( marked >> ), I acknowledge the egg
on my face.  Guess that's not why I stopped using "if(CONST==var)..." after
all (At least I hope not!   :-)     ).     -P. Shenkin

(And also thanks to those who pointed out my error via mail.)

mjs@eagle.UUCP (M.J.Shannon) (04/30/85)

A valid reason for using `for (;;)' rather than `while (1)' is that most
(many, some, etc.) compilers generate a test for the latter and not for
the former.  While these compilers are strictly correct in doing so, it
is sub-optimal....
-- 
	Marty Shannon
UUCP:	ihnp4!eagle!mjs
Phone:	+1 201 522 6063

garys@bunker.UUCP (Gary M. Samuelson) (04/30/85)

> 
> >> To prevent silly mistakes like 
> >> 	if (j = 10)
> >> I usually write
> >> 	if (10 == j)
> >> By putting the constant first, I ensure that the compiler will catch the 
> >> typo.

> Just that instead of writing, in the traditional manner,
> 	if(pc=malloc(nbytes)==NULL)...
> you have to insert extra parens if you use the other form:
> 	if(NULL==(pc=malloc(nbytes)))..

> This is because == has higher precedence than =,

Note that the above statement is true no matter what order is used.

> and the expression will first evaluate NULL==pc,
> then try to set the resulting constant to whatever 
> malloc() returns (except, of course, the compiler doesn't
> let you get that far).

So your example will compare malloc()'s return value with NULL,
and then assign either 'true' or 'false' to pc.  Not too good.

> I used to use the (NULL==var form but reverted to the more traditional
> form because the extra parens kept making me do a double-take.
> I'd rather skip the parens and always put the constant at the end.

I'd rather put in the parens and get correct results.

> Peter S. Shenkin,  Biology, Columbia Univ.   cubsvax!peters

Gary Samuelson

ark@alice.UUCP (Andrew Koenig) (04/30/85)

> Just that instead of writing, in the traditional manner,
>	if(pc=malloc(nbytes)==NULL)...
> you have to insert extra parens if you use the other form:
>	if(NULL==(pc=malloc(nbytes)))..
> This is because == has higher precedence than =, and the expression will
> first evaluate NULL==pc, then try to set the resulting constant to whatever 
> malloc() returns (except, of course, the compiler doesn't let you get that far).

If you write
	if(pc=malloc(nbytes)==NULL)...
that will set pc to 1 if malloc succeeds and 0 if it fails.
You need the parens anyway:
	if((pc=malloc(nbytes)==NULL)...

mac@tesla.UUCP (Michael Mc Namara) (05/01/85)

In article <2140@sun.uucp> shannon@sun.uucp (Bill Shannon) writes:
>> > To prevent silly mistakes like 
>> >         if (j = 10)
>> > I usually write
>> >         if (10 == j)
>> > By putting the constant first, I ensure that the compiler will catch the 
>> > typo.
>> 
>> I think this is a good idea.  Any criticisms?  The only problem
>> I have with it is that I am not accustomed to reading code written
>> this way.
>> -- 
>> Gordon A. Moffett               ...!{ihnp4,cbosgd,sun}!amdahl!gam
>
>What do you mean, any criticisms?  This is one of the most ugly
>perversions of C I've ever seen!  I tend to read this in terms of
>"if variable equals constant" and try to figure out how the value
>"10" is ever going to change!  YUCK YUCK YUCK!!!!
>
>People that write "if (10 == j)" probably also write "while (1)".
>What do you mean, "while 1"???  Are you expecting "1" to change???
>Everyone knows this should be written "for (;;)", read "forever".
>
>                                        Bill Shannon

        While we're setting nets for ourselves, why not 

# define .EQ. ==

        Then we can say if ( j .EQ. 10 ) fortran--;

I believe all this belongs in the crutch box of (weak *) programmers;
  Sure,  you CAN do it if you WANT to, but I'll just 

  %s/.EQ./==/g^M/# define == ==^Mdd^M all your files ;-))))))))
                          ^
                          | 
                          necessary due to first command (-: 

                                                          ^
                                                          |
                           so whats the matter with lefties?
----------------------------------------------------------------------------
I want to go where the climate suits my clothes | mac@tesla | What article?
----------------------------------------------------------------------------

bs@alice.UUCP (Bjarne Stroustrup) (05/01/85)

It is silly to warp ones programs to overcome language and/or compiler
deficiencies (though sometimes necessary). As mentioned before on the net,
it is however trivial for a C compiler to detect most occurrences of the
	if (j = 10)
bug. For example, on seeing that the C++ compiler issues this:
	"warning: constant assignment in condition"

alexis@reed.UUCP (Alexis Dimitriadis) (05/02/85)

>>I think this is a good idea.  Any criticisms?  The only problem
>>I have with it is that I am not accustomed to reading code written
>>this way.

>
>Just that instead of writing, in the traditional manner,
>	if(pc=malloc(nbytes)==NULL)...
>you have to insert extra parens if you use the other form:
>	if(NULL==(pc=malloc(nbytes)))..
>This is because == has higher precedence than =, and the expression will
>first evaluate NULL==pc, then try to set the resulting constant to whatever 
>malloc() returns (except, of course, the compiler doesn't let you get that far).
   Umm, are you SURE about this example?  My compiler assigns operator
precedence regardless of the left-to-right order of the operators,
which is relevant only among operators of the same precedence.  And I have yet 
to hear of a compiler that doesn't.  In fact, pc=malloc(bytes)==NULL 
sets pc to 0 or 1, depending on whether malloc() succeeds.

  At least using NULL==... lets the compiler catch the error.  This 
(constant == lvalue) thing sounds more attractive all the time.

  I guess the reason everybody uses (lvalue==constant) is BECAUSE it looks
like the lvalue=constant construction.  But given the frequency with
which the similarity leads to mistakes, it may be time to get used to
forms that stress the dissimilarity of the operations.  Then there is
less of a chance that a wrong expression will be a valid C construction.
Besides, such constructs can be less ambiguous (easier to read) if used 
consistently, since idioms for different things will look different.

PS. Should customizable pretty printers have a option to move constants
to the left/right of comparisons? :-)

Alexis Dimitriadis
-- 
_______________________________________________
  As soon as I get a regular job, the opinions expressed above
will attach themselves to my employer, who will never be rid of
them again.

	  alexis @ reed
	...ihnp4!{harvard|tektronix}!reed
	...decvax!tektronix!reed
	...teneron!reed

shannon@sun.uucp (Bill Shannon) (05/02/85)

> >I tend to read this in terms of
> >"if variable equals constant" and try to figure out how the value
> >"10" is ever going to change!  YUCK YUCK YUCK!!!!
> 
>   If you expect j to change when you read `if (j == 10)', then you are
> sorely in need of ways to differentiate between assignment and
> comparison!!!

If j can't change, why are you testing whether or not it is equal
to 10 right now?  If j is a constant then pick the appropriate arm
of the if-else and use just it.

					Bill Shannon


P.S.  Don't you just love religious arguments?  I know I'm having fun!

cdshaw@watmum.UUCP (Chris Shaw) (05/02/85)

This argument looks like the kind of nonsense one hears when infix versus 
postfix notation is discussed. Like when in high school, everyone has a
Texas Instruments calculator, and the rich kid in the class brings in a 
Hewlett-Packard for the first time. You get to hear such delightful garbage as:

	'But Reverse Polish isn't NATURAL !!'

similarly with

	'But  "if( 10 == j )"  isn't NATURAL !!'

Come on, folks, surely we are not mindless drones, afraid to think for our
supper ?  The (10==j) idiom is an effective error-catching heuristic, and
its inventor should be viewed with admiration. Anyone who seriously has 
trouble with this minor variation shouldn't be in this business, or should
at least take a more professional attitude.

Chris Shaw    watmath!watmum!cdshaw
University of Waterloo

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

> To prevent silly mistakes like 
> 	if (j = 10)
> I usually write
> 	if (10 == j)
> By putting the constant first, I ensure that the compiler will catch the 
> typo.

Do remember, however, this quote from "A Tour Through the Portable C Compiler":
". . .in cases where a relational operation is being done, and one operand is a
constant, the operands are permuted, and the operator altered, if necessary, to
put the constant on the right."

This means that it will take longer to compile expressions of the form
"(10 == j)" than it will to compile expressions of the form "(j == 10)".  :-)
--
	UUCP: ..decvax!seismo!elsie!ado    ARPA: elsie!ado@seismo.ARPA
	DEC, VAX and Elsie are Digital Equipment and Borden trademarks