philipl@azure.UUCP (Philip Lantz) (04/27/84)
From a style point of view, I personally prefer y = (x == 5); WITH the parentheses, but NOT without them. I think Boolean expressions are as valid a part of the C language as they are of Pascal, even though there is no specific declaration for Boolean variables. However, since I have a compulsion to write the tightest code possible, I use y = 0; if (x == 5) y = 1; What's that? Yes, on every C compiler I've checked (pcc and Ritchie and others) the version with the "if" generates BETTER code than either of the other two forms. (The other two forms generate identical code.) By the way, I agree that the first form above may not be guaranteed to be entirely equivalent to the others, but if y is assigned to a Boolean expression, it should be tested with if (y) if (!y) or possibly if (y == 0) if (y != 0) but never with if (y == 1) if (y != 1) The first four forms generate better code (no compare instruction on most machines), but especially do not depend on the value of a Boolean being 1 when true. Philip Lantz Tektronix, Inc. tektronix!tekmdp!philipl
dwr@ccieng6.UUCP ( Donald Wallace Rouse II) (05/02/84)
xxxxxxxxxxxxxxxxxxxxxxxx > > (1) y = (x == 5); > > > (2) y = 0; > if (x == 5) > y = 1; > > By the way, I agree that the first form above may not be > guaranteed to be entirely equivalent to the others, but if y is > assigned to a Boolean expression, it should be tested with > > if (y) > if (!y) > or possibly > if (y == 0) > if (y != 0) > but never with > if (y == 1) > if (y != 1) According to the K&R bible, p. 41 at the top: Another useful form of type conversion is that relational expressions like i > j and logical expressions connected by && and || are defined to have value 1 if true, and 0 if false. Thus the assignment isdigit = c >= '0' && c <= '9'; sets isdigit to 1 if c is a digit and to 0 if not. Therefore, it IS legal (though bad form, in my opinion) to use the form "(y == 1)" or "(y != 1)". I use this definition occasionally to access arrays, as in: char * tf [] = {"false", "true"}; ... printf ("The supposition that x is 0 is %s\n", tf [x == 0]); D2
amigo@iwlc6.UUCP (John Hobson) (05/04/84)
Well, the results of my poll are in, and here they are. As you will recall, the authors of the book THE C PROGRAMMING LIBRARY gave three examples of code all to assign 1 to the variable y if the value of x was 5, otherwise give y the value of 0. There were three code fragments given by the authors, and one more suggested by me. They are: Version 1 y = 0; if (x == 5) y = 1; Note: When I copied this in my original article, I forgot to indent the third line. Several people took the authors to task for not doing so, but it was not their fault, it was mine. Version 2 (added) if (x == 5) y = 1; else y = 0; Version 3 y = (x == 5) ? 1 : 0; Version 4 y = x == 5; First, before we get to the results, an apology. I stated that on page 52 of Kernighan and Ritchie, False was given a value of 0 and True was given a non-zero value. As several people pointed out, I should have looked on page 38, where True is stated to have a value of 1. Several people split their votes, saying that the formulation used would depend on exactly what the person was trying to do in a particular case. In these cases, I gave each choice 1/2 point. And now, the envelope: In fourth place, with 3 points: Version 1. In third place, with 14 1/2 points: Version 2. In second place, with 26 1/2 points: Version 4. In first place, with 29 points: Version 3. Several comments must be made. Virtually everyone who voted for Version 4, y = x == 5; said that it should be written y = (x == 5); for better readability. Also, with one exception, all the people in favour of this choice said specifically that they would use it only if y was understood to be a Boolean variable. Several people wrote comments that said that they assumed y was Boolean, and a couple of people suggested code along the lines of: y = (x == 5) ? TRUE : FALSE; with TRUE and FALSE defined with appropriate #define statements. One of the points that the authors made was that y = (x==5) generates less code. Well, several people (including I) tried the several choices, and we all got similar results: Guy Harris (rlgvax!guy) sent me this: >> On our VAX-11, running 4.2BSD (which uses the System III C >> compiler and a post-System III optimizer), you get: >> >> first() >> { >> register int x, y; >> >> y = 0; >> if(x == 5) >> y = 1; >> } >> >> generates >> >> .globl _first >> .text >> _first: .word 0xc00 >> clrl r10 >> cmpl r11,$5 >> jneq L1 >> movl $1,r10 >> L1: ret >> >> second() >> { >> register int x, y; >> >> if (x == 5) >> y = 1; >> else >> y = 0; >> } >> >> generates >> >> .globl _second >> .text >> _second:.word 0xc00 >> cmpl r11,$5 >> jneq L2 >> movl $1,r10 >> jbr L1 >> L2: clrl r10 >> L1: ret >> >> which is about what you'd expect, >> >> third() >> { >> register int x, y; >> >> y = (x == 5) ? 1 : 0; >> } >> >> generates >> >> .globl _third >> .text >> _third: .word 0xc00 >> cmpl r11,$5 >> jneq L2 >> movl $1,r0 >> jbr L1 >> L2: clrl r0 >> L1: movl r0,r10 >> ret >> >> which is *worse* than "second"! This is because in >> "second" it's not evaluating the conditional as an >> expression, so it doesn't feel obliged to put the result in >> a register; in "third", however, PCC can only figure out >> how to do this by evaluating the whole mess "(x == 5) ? 1 : >> 0" into a register and then moving the register into "y". >> >> fourth() >> { >> register int x, y; >> >> y = x == 5; >> } >> >> generates >> >> .globl _fourth >> .text >> _fourth:.word 0xc00 >> cmpl r11,$5 >> jneq L2 >> movl $1,r0 >> jbr L1 >> L2: clrl r0 >> L1: movl r0,r10 >> ret >> >> which is *identical* to "third". >> >> Moral: don't always assume you know better than your >> compiler does. I had similar results using "cc -O" on a PDP 11/70, a VAX 11/780, and a 3B20 all running under PWB UNIX 5.0.5. It also works the same way with a DECUS C compiler (machine unspecified). My final comment is something that was well put by Clay Phipps: >> I am disturbed by the notion that the best code is that >> which reflects the deepest knowledge of a particular language. >> This seems to be at odds with the notion of "egoless programming", >> because the authors almost seem to be encouraging displays >> of knowledge, or in other words, "showing off" by >> ego-tripping programmers. The excerpt indicates that the >> authors are indifferent to issues of program clarity and >> readability: they can't define or quantify it, so they've >> decided that they won't worry about it. This is >> particularly disturbing because of the multitude of facilities >> that C provides for writing clever or opaque code (2nd only >> to APL). I suspect that the authors have never been >> required to maintain code written by anyone except themselves. John Hobson AT&T Bell Labs--Naperville, IL ihnp4!iwlc6!amigo