daveh@marob.MASA.COM (Dave Hammond) (07/02/88)
Is different code produce by the compiler for "return n" and "return(n)" ? How about "if (x>1 && y<2)" and "if ((x>1) && (y<2))" ? Do unnecessary parenthesis generate more code ? Dave Hammond UUCP: ...!marob!daveh --------------------------------
chris@mimsy.UUCP (Chris Torek) (07/02/88)
In article <326@marob.MASA.COM> daveh@marob.MASA.COM (Dave Hammond) writes: >Is different code produce by the compiler for "return n" and "return(n)" ? >How about "if (x>1 && y<2)" and "if ((x>1) && (y<2))" ? Do unnecessary >parenthesis generate more code ? For these expressions, one would hope not. On some machines, in certain expressions (including but not limited to floating point arithmetic), `unnecessary' parentheses may cause more code generation under dpANS rules: #define TWICE(x) ((x) + (x)) ... float p, q, r; ... r = TWICE(p + q); expands to r = ((p + q) + (p + q)); which might or might not be equivalent to r = p + p; r += q + q; and if this cannot be determined, must be compiled as r = p + q; r += p + q; /* more or less */ The important problem that is being solved is that a = (b + c) * d; might give 0.0 where a = (b * d) + (c * d); gives `floating point overflow'. Whether this is an ideal solution (or even a not-too-awful one) is another argument entirely.... -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163) Domain: chris@mimsy.umd.edu Path: uunet!mimsy!chris
gwyn@brl-smoke.ARPA (Doug Gwyn ) (07/03/88)
In article <326@marob.MASA.COM> daveh@marob.UUCP (Dave Hammond) writes: >Do unnecessary parenthesis generate more code ? The answer used to be, "not using any reasonable compiler". Under the new ANSI C honoring-parentheses rule, excessive parentheses CAN interfere with code optimization, when they occur in a context that might have been rearranged if the parentheses had not been present. My main objection to excessive parentheses is that they make the code less readable, not more. There are a few cases where the C precedence rules run counter to intuition, and in such cases sparing use of technically redundant parentheses can help the code reader. However, they should not be used just because the code WRITER is unsure. (Most C programmers I know have a copy of the chart from K&R 1st Ed. p. 49 taped up near their terminal.) if ( a < b && b < c ) /* intuitive */ if ( (a < b) && (b < c) ) /* no better */ if ( a << b ^ c | d ) /* have to look this up */ if ( ((a << b) ^ c) | d ) /* no question here */ return 0; /* intuitive */ return(0); /* one wonders why the () are there */
friedl@vsi.UUCP (Stephen J. Friedl) (07/03/88)
In article <8209@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > (Most C programmers I know have a copy of the chart from > K&R 1st Ed. p. 49 taped up near their terminal.) We've found it most helpful to have a little command "opchart" that does this (and it fits on one screen quite nicely): #------------------------ cut here --------------------------- cat << 'EOF' C operator precedence/associativity chart Arity Operator Assoc -------------------------------------------------------------- binary () [] -> . l -> r unary ! ~ ++ -- - (type) * & sizeof r -> l binary * / % l -> r binary + - l -> r binary << >> l -> r binary < <= > >= l -> r binary == != l -> r binary & l -> r binary ^ l -> r binary | l -> r binary && l -> r binary || l -> r ternary ?: r -> l binary = += -= *= /= %= >>= <<= &= ^= |= r -> l binary , l -> r -------------------------------------------------------------- From K&R, p 49 EOF #------------------------ cut here --------------------------- Steve -- Steve Friedl V-Systems, Inc. (714) 545-6442 3B2-kind-of-guy friedl@vsi.com {backbones}!vsi.com!friedl attmail!vsi!friedl -----------Nancy Reagan on John DeLorean: "Just say snow"----------
jeff@unh.UUCP (Jeffrey E. F. Friedl) (07/04/88)
In article <8209@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > [] > return 0; /* intuitive */ > > return(0); /* one wonders why the () are there */ Most likely because _every_ 'return' in K&R-I has those superfluous parens. K&R-II has been "fixed" (I like 'return(e)' beter), but 10 years too late. *jeff* ------------------------------------------------------------------------------- Jeffrey Eric Francis Friedl, Box 2146 Babcock House, Durham New Hampshire 03824 ..!{uunet,decvax}!unh!jeff BITNET%"j_friedl@unhh" ..!ucbvax!kentvax!jfriedl
kenny@m.cs.uiuc.edu (07/06/88)
/* Written 1:29 pm Jul 2, 1988 by gwyn@brl-smoke.ARPA in m.cs.uiuc.edu:comp.lang.c */
> return(0); /* one wonders why the () are there */
If I were asked to guess, I'd guess it's for the same reason that
things like
return (0);
crop up in my code as well. I learned B before I learned C, and B
required that the expression on a return statement be parenthesized,
for no particularly good reason (Although at least one version of B
had return() implemented as a FUNCTION, and not a statement!).
I suspect that Messieurs Kernighan and Ritchie got into the same
habit, for much the same reason, as they were both B programmers
before they did C. Perhaps dmr can enlighten us?
Kevin
" Maynard) (07/06/88)
In article <8209@brl-smoke.ARPA> gwyn@brl.arpa (Doug Gwyn (VLD/VMB) <gwyn>) writes: > return 0; /* intuitive */ To a FORTRAN programmer. > return(0); /* one wonders why the () are there */ 1) Because it looks consistent. 2) It's intuitive to a converted Pascal or PL/I programmer. 3) The programmer has gotten used to putting parentheses around just about everything. -- Jay Maynard, EMT-P, K5ZC...>splut!< | Never ascribe to malice that which can uucp: uunet!nuchat! | adequately be explained by stupidity. hoptoad!academ!uhnix1!splut!jay +---------------------------------------- {killer,bellcore}!tness1! | Birthright Party '88: let's get spaced!
decot@hpisod2.HP.COM (Dave Decot) (07/07/88)
> > return 0; /* intuitive */ > > To a FORTRAN programmer. And to a C programmer. Return is a statement that modifies the default flow of control, such as: goto label; /* NOT goto(label); */ break; /* NOT break(); */ continue; /* NOT continue(); */ Return is not a function call, and it shouldn't look like one. > > return(0); /* one wonders why the () are there */ > > 1) Because it looks consistent. With what? Why do you want to make it easier to confuse function calls with statements that don't come back? > 2) It's intuitive to a converted Pascal or PL/I programmer. Why? Ordinary Pascal has no return statement. > 3) The programmer has gotten used to putting parentheses around just about > everything. That may be true in your case, but it's a bug in the language design. Parentheses are overloaded for all of the following distinct purposes: function calls if, while, and do-while statements casts type construction (used both to indicate functions and for grouping) function declarations evaluation order grouping I see no reason to add further confusion by making flow control look like a function call. I use "return e;" because it's less cluttered and more distinct. Dave Decot hpda!decot
mesard@bbn.com (Wayne Mesard) (07/08/88)
From article <2550075@hpisod2.HP.COM>, by decot@hpisod2.HP.COM (Dave Decot): >> > return 0; /* intuitive */ >> >> To a FORTRAN programmer. > > And to a C programmer. Return is a statement that modifies the default > flow of control, such as: > > goto label; /* NOT goto(label); */ > break; /* NOT break(); */ > continue; /* NOT continue(); */ > Great. I thought the idea of HLL's was to spare the programmer the burden of thinking like s/he was inside the machine. return takes an *expression*. Are there any other statements in the language which have unparenthesized *expressions* in their form? That lil old zero hanging out there by itself LOOKS INCONSISTENT. From the compiler's point of view return is in the set of {goto, break, continue} but this seems an unnatural and confusing view for a programmer to hold in his head. >> 1) Because it looks consistent. > > With what? With the rest of the language (see above). > Why do you want to make it easier to confuse function calls > with statements that don't come back? > Glad you asked. Because it's consistent with the two other statements commonly used to change the flow of control in the middle of a function: exit() and execl(). -- unsigned *Wayne_Mesard(); MESARD@BBN.COM BBN Labs, Cambridge, MA "I am catatonic. And the drinks are on the house." -DB
henry@utzoo.uucp (Henry Spencer) (07/08/88)
> return(0); /* one wonders why the () are there */
Because back in the dawn of time, they were required, and a lot of us
old fogies have never quite gotten out of the habit. Moreover, a lot
of the early C books were written by old fogies, so the habit has been
passed down to later generations by default.
jagardner@watmath.waterloo.edu (Jim Gardner) (07/08/88)
In article <2550075@hpisod2.HP.COM> decot@hpisod2.HP.COM (Dave Decot) writes: >> > return(0); /* one wonders why the () are there */ >> >> 1) Because it looks consistent. > >With what? Why do you want to make it easier to confuse function calls >with statements that don't come back? consider exit() and abort() >I use "return e;" because it's less cluttered and more >distinct. I use return( e ) because the parens highlight the return value. I have no problem reading either, and I suspect most people have no problem with either.
rwl@uvacs.CS.VIRGINIA.EDU (Ray Lubinsky) (07/08/88)
In article <8209@brl-smoke.ARPA>, gwyn@brl-smoke.ARPA (Doug Gwyn ) writes: > My main objection to excessive parentheses is that they > make the code less readable, not more. There are a few > cases where the C precedence rules run counter to intuition, > and in such cases sparing use of technically redundant > parentheses can help the code reader. However, they should > not be used just because the code WRITER is unsure. (Most C > programmers I know have a copy of the chart from K&R 1st Ed. > p. 49 taped up near their terminal.) When I read code I tend to browse, slowing down for the parts the require more thought. Something like if (a < b && b < c && c < d && d < e) is going to stop my scanning a lot more often than if ((a < b) && (b < c) && (c < d) && (d < e)) NOT because I am unaware of C precedence rules but because the first example is devoid of visual structure. Maybe your eye can parse the first as easily as the second, but I have to drop into look-at-it-more-closely mode. If this happens to often it reduces my overall comprehension of the code. I'm sure we'd both agree that the FULL parenthesization of the expression: if ((((a < b) && (b < c)) && (c < d)) && (d < e)) would be abominable -- in my case because it makes the expression hard to scan without thinking about it. As for the "return" business I think it's more clear that return a + b * c; is returning a value when it's written as return(a + b * c); OR EVEN return(a+(b*c)); because in scanning mode I expect a non-void function to return an expression and I catch the concept of here-is-an-expression a lot more quickly when I see those entirely unnecessary parentheses. I also think that entirely unnecessary white space helps readability, but a little execess parenthesization can be an acceptable substitute. -- | Ray Lubinsky, UUCP: ...!uunet!virginia!uvacs!rwl | | Department of BITNET: rwl8y@virginia | | Computer Science, CSNET: rwl@cs.virginia.edu -OR- | | University of Virginia rwl%uvacs@uvaarpa.virginia.edu |
walter@hpcllz2.HP.COM (Walter Murray) (07/09/88)
Dave Decot writes: >Return is not a function call, and it shouldn't look like one. I agree, and I don't use parentheses there. But how do people feel about sizeof, which is also not an operator and does not require parentheses when its operand is an expression? I hate to use them, but it seems they always improve readability in that case. Am I just braindamaged from too much Pascal? Walter Murray
dg@lakart.UUCP (David Goodenough) (07/09/88)
From article <326@marob.MASA.COM>, by daveh@marob.MASA.COM (Dave Hammond): > Is different code produce by the compiler for "return n" and "return(n)" ? > > How about "if (x>1 && y<2)" and "if ((x>1) && (y<2))" ? Do unnecessary > parenthesis generate more code ? These two expressions *_SHOULD_* generate the same code on any decent self respecting compiler (They do even on BDS C 1.43 under CP/M :-). It is worth noting that this is a weakness of RD parsers: the amount of work incurred by unnecessary parentheses is quite considerable, especially in a language such as C, with 15 levels of operator precedence. As for LR parsers I don't know - I have not studied them to the same degree. The reason why people tend to parenthesize where it is not needed is to increase clarity. Quick - do these two mean the same: if ((a == 1 && b == 2) || (c == 3 && d == 4)) if (a == 1 && b == 2 || c == 3 && d == 4) In the first case, my intention is much clearer (to myself included). I believe (as do many others) that parentheses serve a double function: overriding the normal precedence of operators, AND making things readable. -- dg@lakart.UUCP - David Goodenough +---+ | +-+-+ ....... !harvard!cca!lakart!dg +-+-+ | +---+
sullivan@vsi.UUCP (Michael T Sullivan) (07/09/88)
In article <2550075@hpisod2.HP.COM>, decot@hpisod2.HP.COM (Dave Decot) writes: > > Return is not a function call, and it shouldn't look like one. > > > > return(0); /* one wonders why the () are there */ > > > > 1) Because it looks consistent. > > With what? Why do you want to make it easier to confuse function calls > with statements that don't come back? Like exit() or abort()??? > I see no reason to add further confusion by making flow control look like > a function call. I use "return e;" because it's less cluttered and more > distinct. When I have something like: return(a == b ? c : d); I think it looks better than: return a == b ? c : d; Maybe if return had a space between the paren like while, for, and switch everybody would be happy (and there'd be peace in the world, and no more smog, ...). I think I'll try that for a while and see how it goes. -- Michael Sullivan {uunet|attmail}!vsi!sullivan V-Systems, Inc. Santa Ana, CA sullivan@vsi.com ons, workstations, workstations, workstations, workstations, workstations, work
nevin1@ihlpf.ATT.COM (00704a-Liber) (07/09/88)
In article <2550075@hpisod2.HP.COM> decot@hpisod2.HP.COM (Dave Decot) writes: |> 3) The programmer has gotten used to putting parentheses around just about |> everything. |That may be true in your case, but it's a bug in the language design. If it is truly a bug, how would you propose fixing it? |Parentheses are overloaded for all of the following distinct purposes: | function calls | if, while, and do-while statements | casts | type construction (used both to indicate functions and for grouping) | function declarations | evaluation order grouping Since 'return' can return an expression, parentheses are always allowed (but never required). Does it really matter whether they are there or not? Is it really any harder to understand a program that has them vs. one that does not? |I see no reason to add further confusion by making flow control look like |a function call. I use "return e;" because it's less cluttered and more |distinct. For the case of a constant or a single variable, I do too. But on those few occasions that I have to return an expression (instead of using a tmp variable and returning that), I sometimes put parentheses around the expression. If it makes it easier to read, then put them in. Otherwise, (as long as it doesn't make it harder to read), it really shouldn't matter. -- _ __ NEVIN J. LIBER ..!ihnp4!ihlpf!nevin1 (312) 510-6194 ' ) ) You are in a maze of little twisty / / _ , __o ____ email paths, all different. / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
ado@elsie.UUCP (Arthur David Olson) (07/10/88)
I leave out the parentheses in a return whatever; statement; this ensures that if I mistakenly write retunr whatever; I'll get a warning at compile time--along with a line number--rather than an "Undefined: _retunr" error at link time (with no indication of where the error is) as would be true if I wrote retunr(whatever); (which the compiler would take to be a function call.) Of course this advice applies only to those of us who make mistakes. -- ado@ncifcrf.gov ADO is a trademark of Ampex.
wes@obie.UUCP (Barnacle Wes) (07/10/88)
In article <2550075@hpisod2.HP.COM>, decot@hpisod2.HP.COM (Dave Decot) writes: > I see no reason to add further confusion by making flow control look like > a function call. I use "return e;" because it's less cluttered and more > distinct. I agree. I also try to make the flow-control statements that REQUIRE parenthesis (if, while, & for) look different, too. I always write functions with the parentheses immediately following the name, i.e. function(), and control statements with whitespace between the statment and the parentheses, i.e. if (something) and while (braindead). -- {hpda, uwmcsd1}!sp7040!obie!wes "Happiness lies in being priviledged to work hard for long hours in doing whatever you think is worth doing." -- Robert A. Heinlein --
mdf@tut.cis.ohio-state.edu (Mark D. Freeman) (07/11/88)
In <2550075@hpisod2.HP.COM> decot@hpisod2.HP.COM (Dave Decot) writes: >Return is a statement that modifies the default >flow of control, such as: > > goto label; /* NOT goto(label); */ > break; /* NOT break(); */ > continue; /* NOT continue(); */ > >Return is not a function call, and it shouldn't look like one. > >Why do you want to make it easier to confuse function calls >with statements that don't come back? What about exit()? Does it require parenthesis? How does it fit into your argument? ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` ` -- Mark D. Freeman (614) 262-1418 Applications Programmer, CompuServe mdf@tut.cis.ohio-state.edu [70003,4277] ...!att!tut.cis.ohio-state.edu!mdf Columbus, OH Guest account at The Ohio State University
henry@utzoo.uucp (Henry Spencer) (07/11/88)
> ... this is a weakness of RD parsers: the amount of > work incurred by unnecessary parentheses is quite considerable, especially > in a language such as C, with 15 levels of operator precedence.... Well, yes, *if* you implement the RD parser straight from the grammar and do no optimization. One can do better, at the price of greater complexity, by explicitly looking for the simple cases. -- Anyone who buys Wisconsin cheese is | Henry Spencer @ U of Toronto Zoology a traitor to mankind. --Pournelle | {ihnp4,decvax,uunet!mnetor}!utzoo!henry
levy@ttrdc.UUCP (Daniel R. Levy) (07/11/88)
In article <17458@tut.cis.ohio-state.edu>, mdf@tut.cis.ohio-state.edu (Mark D. Freeman) writes: > In <2550075@hpisod2.HP.COM> decot@hpisod2.HP.COM (Dave Decot) writes: > >Return is a statement that modifies the default > >flow of control, such as: > > goto label; /* NOT goto(label); */ > > break; /* NOT break(); */ > > continue; /* NOT continue(); */ > >Return is not a function call, and it shouldn't look like one. > >Why do you want to make it easier to confuse function calls > >with statements that don't come back? > What about exit()? Does it require parenthesis? How does it fit into > your argument? Butting in, I say: exit() is a bona fide, real, genuine, honest-to-goodness FUNCTION CALL. It just so happens that the usual effect of calling it (besides miscellaneous cleanup actions, such as flushing any open stdio buffers) is to stop execution of the program that called it. Were you to feel a bit wild and crazy some time, you could perfectly well write your own exit() which could do whatever oddball things it wished and not stop the program at all when called. E.g., exit(i) int i; { printf("nyah nyah you tried to exit %d\n", i); } "return" is DEFINED as stopping execution of the FUNCTION that called it and returning control (and a value, if specified) to "whatever" called that function, whether it was another function, or some veiled-from-view system mechanism (as with main() or as an interrupt handler). -- |------------Dan Levy------------| THE OPINIONS EXPRESSED HEREIN ARE MINE ONLY | AT&T Data Systems Group | AND ARE NOT TO BE IMPUTED TO AT&T. | Skokie, Illinois | |-----Path: att!ttbcad!levy-----|
jfh@rpp386.UUCP (John F. Haugh II) (07/12/88)
In article <1988Jul10.201845.27751@utzoo.uucp> henry@utzoo.uucp (Henry Spencer) writes: >> ... this is a weakness of RD parsers: the amount of >> work incurred by unnecessary parentheses is quite considerable, especially >> in a language such as C, with 15 levels of operator precedence.... > >Well, yes, *if* you implement the RD parser straight from the grammar and >do no optimization. One can do better, at the price of greater complexity, >by explicitly looking for the simple cases. one of the major strengths of r-d parsers is you can code the parser straight from the grammar. performing the transformations from left to right recursion should be fairly automatic and is the only really worthwhile (ease of coding, speed and complexity tradeoffs being considered) optimization i can see. the geneal case of trying to reduce the recursion present in the parser would seem to require a potentially arbitrary amount of look ahead, or as a minimum, the same amount of lookahead as the length of the shortest sentence the parser is trying to recognize. clarifications, henry? >Anyone who buys Wisconsin cheese is | Henry Spencer @ U of Toronto Zoology >a traitor to mankind. --Pournelle | {ihnp4,decvax,uunet!mnetor}!utzoo!henry and what the hell does this mean??? - john. -- John F. Haugh II +--------- Cute Chocolate Quote --------- HASA, "S" Division | "USENET should not be confused with UUCP: killer!rpp386!jfh | something that matters, like CHOCOLATE" DOMAIN: jfh@rpp386.uucp | -- with my apologizes
bill@proxftl.UUCP (T. William Wells) (07/13/88)
In article <8108@elsie.UUCP>, ado@elsie.UUCP (Arthur David Olson) writes: > I leave out the parentheses in a > return whatever; > statement; this ensures that if I mistakenly write > retunr whatever; > I'll get a warning at compile time--along with a line number--rather than > an "Undefined: _retunr" error at link time (with no indication of where the > error is) as would be true if I wrote > retunr(whatever); > (which the compiler would take to be a function call.) This is the first non-esthetic reason I've seen for not putting in the parentheses; I'd note that it does not always work, consider: retunr (a+b)*c;. Oh, well, nobody said programming was going to be trivial... Just to add some data to the discussion, here is what we do. o No function call has a space after the function descriptor. o Every keyword except sizeof is always followed by a space, newline, or semicolon. o Sizeof is always formatted as if it were a function call. Actually, we code no space after the sizeof because it is a unary operator and we parenthesize for uniformity; this makes it look like a function call. o For purely Hysterical Raisons we always use parentheses around the expression. I think we'd change except for inertia and the pain of reformatting all the code of a new version of a product. My own opinion on the use of parentheses is that almost any consistent style is better than no style at all. The differences between most styles is a matter of esthetics; one may choose almost any style one pleases and be "right".
dmg@ssc-vax.UUCP (David Geary) (07/13/88)
In article <175@lakart.UUCP>, David Goodenough writes: > > if ((a == 1 && b == 2) || (c == 3 && d == 4)) > > if (a == 1 && b == 2 || c == 3 && d == 4) > >In the first case, my intention is much clearer (to myself included). > >I believe (as do many others) that parentheses serve a double function: >overriding the normal precedence of operators, AND making things readable. "Unnecessary" parenthesis are something I use all the time in macro definitions, also. Consider: #define Square(x) x*x #define GetNextChar(c) c = getchar() main() { int x=2, i=0; char ch; char string[100]; while(GetNextChar(ch) != '\n') string[i++] = ch; printf("Square of 3 is: %d\n", Square(x+1)); printf("String is %s\n", string); } 1) The string is never read in, because the while statement expands to: while(ch = getchar() != `\n`) != has precedence over =, so the character is read by getchar(), then it is compared to '\n'. If the character was a newline, ch gets assigned the value 1, if the character was not a newline, then it gets assigned the value 0. (NULL ?? ;-)) 2) Square(x+1) expands to: x+1*x+1 which is: x+x+1. In our case, we get: Square of 3 is: 5. The above two macros should have been written like: #define Square(x) (x)*(x) #define GetNextChar(c) (c = getchar()) And now, everything will work as expected. The moral of the story is: 1) I always put parenthesis around all tokens in macros. 2) I always put parenthesis around the entire macro definition. Sometimes, of course, the parenthesis are unnecessary, but it sure helps eliminate some nasty bugs. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ "...Raven hair and ruby lips, ~ ~ Sparks Fly from the fingertips..." ~ ~ ~ ~ Witchy Woman, The Eagles ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~ David Geary, Boeing Aerospace, ~ ~ Seattle - "THE DRIZZLE CAPITAL OF THE WORLD" ~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
smryan@garth.UUCP (Steven Ryan) (07/14/88)
>the geneal case of trying to reduce the recursion present in the parser >would seem to require a potentially arbitrary amount of look ahead, or >as a minimum, the same amount of lookahead as the length of the shortest >sentence the parser is trying to recognize. clarifications, henry? I'm not Henry, but ..... A context free grammar is union of Dyck set and a linear (regular expression) grammar. The regular expression part of the grammar can be parsed with loops and conditionals (actually just an FSM) and recursion isn't necessary. One of the optimisations is to recognise linear parts of language and translate them into your favorite version of an FSM. C has three symbol pairs which form embedding constructs: () [] {}. [] can be embedded in (), () in [], and () and [] in {} so that in general, some form of stack is necessary. This can still be optimise some what by counting when () is directly embedded in (), [] in [], {} in {}, instead of stacking. In something like ((a+b)+c[(d)]) the expression scanner can count the parentheses and only need recurse to handle the subscript: ((a+b)+c[(d)]) expr: 12 2 1 subscript: 1 1 expr: 1 1 Because on most machines, recursion is slower than looping, it is a tradeoff between a more complicated or faster parser. >>Anyone who buys Wisconsin cheese is | Henry Spencer @ U of Toronto Zoology >>a traitor to mankind. --Pournelle | {ihnp4,decvax,uunet!mnetor}!utzoo!henry > >and what the hell does this mean??? Does anybody even try to understand? Hafa an godne daege. sm ryan
news@ism780c.isc.com (News system) (07/14/88)
In article <5253@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704a-Liber,N.J.) writes: >Since 'return' can return an expression, parentheses are always allowed >(but never required). This is not quite right. A procedure may return a void expression. But parantheses may NOT enclose a void experssion. Thus statement: return (); is malformed. This is the reason that I chose not to use redundant parens on returned expressions. Marv Rubinstein
nevin1@ihlpf.ATT.COM (00704a-Liber) (07/14/88)
In article <2089@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: >"Unnecessary" parenthesis are something I use all the time in macro >definitions, also. Most of the parentheses in macros ARE necessary as you have shown (but are usually not sufficient as I will show). >Consider: >#define Square(x) x*x [David shows why this macro should be redefined as #define Square(x) ((x)*(x)) ] but consider the case where you try the following: int x; x = 2; (void)printf("The square of %d + 1 is %d.\n", x, Square(++x)); The Square macro does not work correctly because the argument has side effects (this is why parentheses are not sufficient in macros). -- _ __ NEVIN J. LIBER ..!att!ihlpf!nevin1 (312) 510-6194 ' ) ) You are in a little twisty maze of / / _ , __o ____ email paths, all different. / (_</_\/ <__/ / <_ These are solely MY opinions, not AT&T's, blah blah blah
karl@haddock.ISC.COM (Karl Heuer) (07/15/88)
In article <11925@ism780c.isc.com> marv@ism780.UUCP (Marvin Rubenstein) writes: |In article <5253@ihlpf.ATT.COM> nevin1@ihlpf.UUCP (00704a-Liber,N.J.) writes: |>Since 'return' can return an expression, parentheses are always allowed |>(but never required). | |This is not quite right. A procedure may return a void expression. But |parantheses may NOT enclose a void experssion. Thus statement: | return (); |is [syntactically] malformed. This is not quite right either. The empty string does not denote a void expression. A void function may not return a void expression, either with or without the parens: "void f() { return exit(0); }" violates a constraint. Karl W. Z. Heuer (ima!haddock!karl or karl@haddock.isc.com), The Walking Lint
paul@arthur.uchicago.edu (Paul Burchard) (07/21/88)
In article <2089@ssc-vax.UUCP> dmg@ssc-vax.UUCP (David Geary) writes: >"Unnecessary" parenthesis are something I use all the time in macro >definitions, also. Consider: > >#define Square(x) x*x >#define GetNextChar(c) c = getchar() > [...] >The above two macros should have been written like: > >#define Square(x) (x)*(x) >#define GetNextChar(c) (c = getchar()) > [...] >~ David Geary, Boeing Aerospace, ~ >~ Seattle - "THE DRIZZLE CAPITAL OF THE WORLD" ~ Actually, they should have been written like #define Square(x) ((x)*(x)) #define GetNextChar(c) ((c) = getchar()) I trust you can imagine code that requires these further parens. ----------------------------------------------------------------------------- Paul Burchard paul@zaphod.UChicago.Edu enum Chicago_weather { roast, freeze, steam, dry, simmer } today; -----------------------------------------------------------------------------
steve@oakhill.UUCP (steve) (07/26/88)
I'm sorry I can't include the text I'm mentioning since I'm haveing net reply problems, but I'll fake it as best I can. In an absolute sense > #define square(x) (x * x) shouldn't be : > #define square(x) ((x) * (x)) it should be : > #define square(x) (temp = (x),(temp * temp)) in order to avoid problems with sending in a post incremented variable; BUT, - as with everything else in C, either of the first two forms are good if you're careful and know what you're doing. Form 1 works if you know you're sending in a simple variable. Form 2 works if you are not sending in an expression that changes the variable. Form 3 is slower than the other two, but more conservative. Use your best judgement - macros are dangerous thing if not used carefully That is why C compilers have a -P option. Your mooncalf - Steve To: paul@zaphod.UChicago.Edu Subject: Re: Unnecessary Parenthesis Newsgroups: comp.lang.c In-Reply-To: <441@kaon.uchicago.edu> References: <2089@ssc-vax.UUCP> Organization: Motorola Inc., Austin Tx. Cc: Bcc: I'm sorry I can't include the text I'm mentioning but > #define square(x) (x * x) shouldn't be : > #define square(x) ((x) * (x)) it should be : > #define square(x) (temp = (x),(temp * temp)) in order to avoid problems with sending in a post incremented variable; BUT, - as with everything else in C, either of the first two forms are good if you're careful and know what you're doing. Form 1 works if you know you're sending in a simple variable. Form 2 works if you are not sending in an expression that changes the variable. Form 3 is slower than the other two, but more conservative. Your mooncalf - Steve From steve Mon Jul 25 13:54:49 1988 Return-Path: <steve> Received: by devsys.com (3.2/SMI-3.2) id AA13794; Mon, 25 Jul 88 13:54:49 CDT Date: Mon, 25 Jul 88 13:54:49 CDT From: steve Message-Id: <8807251854.AA13794@devsys.com> To: paul@zaphod.UChicago.Edu Subject: Re: Unnecessary Parenthesis Newsgroups: comp.lang.c In-Reply-To: <441@kaon.uchicago.edu> References: <2089@ssc-vax.UUCP> Organization: Motorola Inc., Austin Tx. Cc: I'm sorry I can't include the text I'm mentioning but having sending problems. I'l try to fake it. > #define square(x) (x * x) shouldn't be : > #define square(x) ((x) * (x)) it should be : > #define square(x) (temp = (x),(temp * temp)) in order to avoid problems with sending in a post incremented variable; BUT, - as with everything else in C, either of the first two forms are good if you're careful and know what you're doing. Form 1 works if you know you're sending in a simple variable. Form 2 works if you are not sending in an expression that changes the variable. Form 3 is slower than the other two, but more conservative. Your mooncalf - Steve To: paul@zaphod.UChicago.Edu Subject: Re: Unnecessary Parenthesis Newsgroups: comp.lang.c In-Reply-To: <441@kaon.uchicago.edu> References: <2089@ssc-vax.UUCP> Organization: Motorola Inc., Austin Tx. Cc: Bcc: I'm sorry I can't include the text I'm mentioning but > #define square(x) (x * x) shouldn't be : > #define square(x) ((x) * (x)) it should be : > #define square(x) (temp = (x),(temp * temp)) in order to avoid problems with sending in a post incremented variable; BUT, - as with everything else in C, either of the first two forms are good if you're careful and know what you're doing. Form 1 works if you know you're sending in a simple variable. Form 2 works if you are not sending in an expression that changes the variable. Form 3 is slower than the other two, but more conservative. Your mooncalf - Steve To: paul@zaphod.UChicago.Edu Subject: Re: Unnecessary Parenthesis Newsgroups: comp.lang.c In-Reply-To: <441@kaon.uchicago.edu> References: <2089@ssc-vax.UUCP> Organization: Motorola Inc., Austin Tx. Cc: Bcc: I'm sorry I can't include the text I'm mentioning but having sending problems. I'l try to fake it. > #define square(x) (x * x) shouldn't be : > #define square(x) ((x) * (x)) it should be : > #define square(x) (temp = (x),(temp * temp)) in order to avoid problems with sending in a post incremented variable; BUT, - as with everything else in C, either of the first two forms are good if you're careful and know what you're doing. Form 1 works if you know you're sending in a simple variable. Form 2 works if you are not sending in an expression that changes the variable. Form 3 is slower than the other two, but more conservative. Your mooncalf - Steve > Nothing I say is quoteable - so don't expect to see anything important here.
steve@oakhill.UUCP (steve) (07/26/88)
extremely sorry for the previous mail. I'm not too go at this yet. Be gentill - I'm new at this. your - mooncalf - Steve
karzes@mfci.UUCP (Tom Karzes) (07/26/88)
In article <1401@devsys.oakhill.UUCP> steve@oakhill.UUCP (steve) writes: }I'm sorry I can't include the text I'm mentioning since I'm haveing net }reply problems, but I'll fake it as best I can. }In an absolute sense }> #define square(x) (x * x) }shouldn't be : }> #define square(x) ((x) * (x)) }it should be : }> #define square(x) (temp = (x),(temp * temp)) }in order to avoid problems with sending in a post incremented variable; This doesn't work in general in C for a number of reasons. First, C is not an expression language, so you can't declare temp to be local to the expression. This means it has to either be global or defined by the client (and of course, this requires fixing its type, but I won't complain about that). Second, even if you could declare it locally, you'd have to be careful about the name you used to avoid a name conflict with a variable used in the expression for x.
sar@datcon.UUCP (Simon A Reap) (09/23/88)
(old discussion, but our News was gebustenbroken for yonks) In article <1401@devsys.oakhill.UUCP> steve@oakhill.UUCP (steve) writes three alternatives for the square(x) macro: >> #define square(x) (x * x) >> #define square(x) ((x) * (x)) >> #define square(x) (temp = (x),(temp * temp)) > Please note, the third version is *dangerous*. An expression such as: z = square(x) + square(y); expands to: z = (temp = (x),(temp * temp)) + (temp = (y),(temp * temp)); which looks OK, but note that, although C guarantees to perform the assignment (temp = (x)) before the multiplication (temp * temp) in each expansion of square(x), but it does *not* guarantee to complete the first expansion before it starts the second (or vice versa). I have seen at least 2 compilers which do the first assignment, then the second assignment (to the same 'temp' variable), followed by the 2 multi- plications, so you end up with the same value of 'temp' squared twice. Does anyone know how to get round this problem? Please!! (it's been bugging us for months :-( ) -- Enjoy, yerluvinunclesimon Opinions are mine - I don't even have a cat Reach me at sar@datcon.co.uk, or ...!mcvax!ukc!pyrltd!datcon!sar
gwyn@smoke.ARPA (Doug Gwyn ) (09/25/88)
In article <23@datcon.UUCP> sar@datcon.co.uk (Simon A Reap) writes: > z = square(x) + square(y); >Does anyone know how to get round this problem? Please!! z = x*x + y*y;