brown@vidiot.UUCP (Vidiot) (02/26/91)
I am running ISC 2.0.2 Unix and ISC text processing package. When I have the following line, with neither of the registers set on the command line: .if \nG==1&\nI==0 \{\ .tm inside coverdef G=\nG I=\nI It gets past the if statement and shows that both registers are indeed zero. If I change the order of the test, like this: .if \nI==0&\nG==1 \{\ .tm inside coverdef G=\nG I=\nI It doesn't get to the next statement, just as I would expect. If I do -rG1 on the command line, then it gets past the if statement, as I expected. What the Hell is going on here? Is the ISC version of DWB 2.0 broke? -- harvard\ att!nicmad\ spool.cs.wisc.edu!astroatc!vidiot!brown Vidiot ucbvax!uwvax..........!astroatc!vidiot!brown rutgers/ decvax!nicmad/ INTERNET:vidiot!brown%astroatc@spool.cs.wisc.edu
brown@vidiot.UUCP (Vidiot) (02/26/91)
In article <1434@vidiot.UUCP> brown@vidiot.UUCP (Vidiot) writes:
<
<I am running ISC 2.0.2 Unix and ISC text processing package. When I have
<the following line, with neither of the registers set on the command line:
<
< .if \nG==1&\nI==0 \{\
< .tm inside coverdef G=\nG I=\nI
<
<It gets past the if statement and shows that both registers are indeed zero.
<
<If I change the order of the test, like this:
<
< .if \nI==0&\nG==1 \{\
< .tm inside coverdef G=\nG I=\nI
<
<It doesn't get to the next statement, just as I would expect. If I do -rG1
<on the command line, then it gets past the if statement, as I expected.
<
<What the Hell is going on here? Is the ISC version of DWB 2.0 broke?
As it turns out, groff 1.00 does the same thing. Why is the order of testing
important?
BTW, just in case it needs to be said exactly what I want to happen, what I am
after is that the code after the if statement will only be executed IF the
I number register is equal to a 0 AND the G number register is equal to a 1.
--
harvard\ att!nicmad\ spool.cs.wisc.edu!astroatc!vidiot!brown
Vidiot ucbvax!uwvax..........!astroatc!vidiot!brown
rutgers/ decvax!nicmad/ INTERNET:vidiot!brown%astroatc@spool.cs.wisc.edu
jeff@itx.isc.com (Jeff Copeland) (02/28/91)
In article <1434@vidiot.UUCP> brown@vidiot.UUCP (Vidiot) writes: > >I am running ISC 2.0.2 Unix and ISC text processing package. When I have >the following line, with neither of the registers set on the command line: > > .if \nG==1&\nI==0 \{\ > .tm inside coverdef G=\nG I=\nI > >It gets past the if statement and shows that both registers are indeed zero. >.... >What the Hell is going on here? Is the ISC version of DWB 2.0 broke? The secret is evaluation order: if you add parentheses: .if (\nI==0)&(\nG==1) \{\ it works as you expect. So the line in the DWB 2.0 docs that says: "Except where controlled by parentheses, evaluation of expressions is left-to-right." is *really* true. By the way, Interactive's DWB 2.0, IBM's DWB 2.0 on the RS/6000, DWB 1.0 on a VAX running BSD, and old troff as ported by BRL to BSD, all act the same on this fragment.
jaap@mtxinu.COM (Jaap Akkerhuis) (02/28/91)
In article <1435@vidiot.UUCP> brown@vidiot.UUCP (Vidiot) writes: > In article <1434@vidiot.UUCP> brown@vidiot.UUCP (Vidiot) writes: > < > <I am running ISC 2.0.2 Unix and ISC text processing package. When I have > <the following line, with neither of the registers set on the command line: > < > < .if \nG==1&\nI==0 \{\ > < .tm inside coverdef G=\nG I=\nI > < > <It gets past the if statement and shows that both registers are indeed zero. > < > <If I change the order of the test, like this: > < > < .if \nI==0&\nG==1 \{\ > < .tm inside coverdef G=\nG I=\nI > < > <It doesn't get to the next statement, just as I would expect. If I do -rG1 > <on the command line, then it gets past the if statement, as I expected. > < > <What the Hell is going on here? Is the ISC version of DWB 2.0 broke? Remember that famous line from the manual: ``evaluation is from left to right''? So in this case, the & doesn't take precedence over the == as it would in C (if (G == 1 && I == 0) What you want to do, is to put the test in paratheses as in .if (nG==1)&(\nI==0) .tm condition is true > > As it turns out, groff 1.00 does the same thing. Why is the order of testing > important? > Groff is correctly implementating the left-to-right evaluation rule. Anyway, a lot of people forget about this so they resort to .if \nI==0 .if \nG==1 Common idiom in a macro pacakge is: .if !\nI .if \nG .tm true which is actually a different test (in C: if( I != 0 && G == 0) ) jaap PS. I assume that you know that you have to double the backslahes inside a macro. I guess you didn't want to shoe all these trivial details.
msb@sq.sq.com (Mark Brader) (03/05/91)
"Vidiot" asked why .if \nG==1&\nI==0 ... didn't work. Jaap Akkerhuis diagnosed correctly that Vidiot had forgotten troff's rather counterintuitive rule of no precedence, and suggested the following (or intended to suggest it, anyway; I have fixed a typo): > What you want to do, is to put the test in parentheses as in > .if (\nG==1)&(\nI==0) .tm condition is true And this is right. Jaap also observed that some people would say one of: > .if \nI==0 .if \nG==1 > .if !\nI .if \nG .tm true and that these are different if I and G are not really booleans. However, he falls from grace in saying that the second one is equivalent to the C code: > if( I != 0 && G == 0) First, the conditions are reversed, but again, that's incidental. The more important thing is this. In troff, when an integer value is treated as boolean, *only* a *positive* value is considered true. This is counterintuitive for C programmers, who are used to any nonzero value being considered true. The last line of troff above is thus actually equivalent to *this* in C: if (I <= 0 && G > 0) -- Mark Brader "The default choice ... is in many ways the most utzoo!sq!msb important thing. ... People can get started without msb@sq.com reading a big manual." -- Brian W. Kernighan This article is in the public domain.