xor@aix01.aix.rpi.edu (Joseph Schwartz) (04/02/91)
In article <1991Apr1.203600.15721@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes: >In article <4072.27f7215c@iccgcc.decnet.ab.com> browns@iccgcc.decnet.ab.com (Stan Brown) writes: >>I bet if you stopped 100 C programmers, more than 50 of 'em would tell >>you that parentheses are part of the return statement, just like if, >>while, do, and for. They're not. > >They used to be, actually, and many of the role models :-) for C programmers >have habits dating back to the time when they were. Is this true? The grammar in K&R1 (pg 218) does not require parens in the return statement. However, the example on page 68 (and indeed all of the examples in the book) show the parentheses around the expression. Another place I tend to see unnecessary parens is with the sizeof operator. You can use "sizeof (typename)" or "sizeof expression"... I often see "sizeof (expression)"...usually there's no space between the sizeof and the left paren, which may reinforce the belief that the parens "belong to" the sizeof operator. Just curious...how often do you folks purposely insert unnecessary parens into expressions? Sometimes I'll do it just to make the grouping clearer (just in case the next person to read the code doesn't know all the precedence rules by heart). I'm talking about expressions in general, not just in conjunction with return or sizeof. -- Joe Schwartz Internet: xor@mts.rpi.edu Bitnet: userez3n@rpitsmts
henry@zoo.toronto.edu (Henry Spencer) (04/03/91)
In article <1#.gqcm@rpi.edu> xor@aix01.aix.rpi.edu (Joseph Schwartz) writes: >>They used to be, actually, and many of the role models :-) for C programmers >>have habits dating back to the time when they were. > >Is this true? The grammar in K&R1 (pg 218) does not require parens in the >return statement. However, the example on page 68 (and indeed all of the >examples in the book) show the parentheses around the expression. It's true. A lot of us Real Old Timers remember when K&R1 came out. The parentheses stopped being mandatory somewhat before that. BWK and DMR picked up the habit when they were still required, as did others. >Another place I tend to see unnecessary parens is with the sizeof >operator. You can use "sizeof (typename)" or "sizeof expression"... >I often see "sizeof (expression)"... I think this is a combination of (a) paranoia about operator precedence, and (b) a general feeling that treating this funny operator as if it were a function gives a cleaner appearance. >Just curious...how often do you folks purposely insert unnecessary parens >into expressions? Sometimes I'll do it just to make the grouping clearer... Parentheses inserted to make grouping clearer are "unnecessary" only to the compiler; almost nobody really has the C precedence rules memorized. -- "The stories one hears about putting up | Henry Spencer @ U of Toronto Zoology SunOS 4.1.1 are all true." -D. Harrison| henry@zoo.toronto.edu utzoo!henry
shaunc@gold.gvg.tek.com (Shaun Case) (04/03/91)
In article <1#.gqcm@rpi.edu> xor@aix01.aix.rpi.edu (Joseph Schwartz) writes: > >Just curious...how often do you folks purposely insert unnecessary parens >into expressions? Sometimes I'll do it just to make the grouping clearer >(just in case the next person to read the code doesn't know all the >precedence rules by heart). I'm talking about expressions in general, >not just in conjunction with return or sizeof. > I probably use more "unnecessary" parens than most people -- I go to a lot of trouble to make sure my code is readable and maintainable. I figure that if the compiler is smart enough to optimize away unnecessary parentheses, why not use them if it make the code easier to follow? I often have rather large compilcated compound if statements, and the format I have found that works best for me is: if ( (test 1) || (test 2) || (test 3) || (test 4) ) { whatever(); whatever2(); etc(); } This ensures that when someone changes the code, it doesn't break immediately due to relying solely on precenence. It also allows you to put a comment off to the side for each test case. I also put parens around return values, because sometimes I change returns to exit()s, and it helps to have the parens there already, rather than waiting for the compiler to point it out. Of course, you didn't have to worry about things like this when you were writing in BASIC on your C64 with 38K of free ram, since you could fill up the entire memory space in a weekend, and be finished with your program, and never have to look at it again... those were the days! :-) // Shaun // -- Shaun Case: shaunc@gold.gvg.tek.com or atman%ecst.csuchico.edu@RELAY.CS.NET or Shaun Case of 1:119/666.0 (Fidonet) or 1@9651 (WWIVnet) --- It's enough to destroy a young moose's faith!
r3jjs@VAX1.CC.UAKRON.EDU (Jeremy J Starcher) (04/03/91)
In article <1#.gqcm@rpi.edu> xor@aix01.aix.rpi.edu (Joseph Schwartz) writes: >In article <1991Apr1.203600.15721@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes: >Just curious...how often do you folks purposely insert unnecessary parens >into expressions? Sometimes I'll do it just to make the grouping clearer >(just in case the next person to read the code doesn't know all the >precedence rules by heart). I'm talking about expressions in general, >not just in conjunction with return or sizeof. > I use paren's all the time. The first C compiler I ever used had *no* orders of operations. It did things left to right. Period. So... I got into the habit of putting parens around everthing. This was then aggrivated when the language we used at work had a *different* order of operation than the C compiler I used at home. So, I will put parens around everthing so I am sure how it will be evaluated and for clarity. ie. if ( (a == 10) && (ful == FALSE) ) return ( (bar*10) +1); etc. -- --------------------------+--------------------------------------------------- Jeremy J Starcher ! No programmer programs in LOGO after reaching r3jjs@vax1.cc.uakron.edu ! age 14... r3jjs@akronvm.bitnet !
jmm@eci386.uucp (John Macdonald) (04/08/91)
In article <1991Apr2.185204.20516@zoo.toronto.edu> henry@zoo.toronto.edu (Henry Spencer) writes: |Parentheses inserted to make grouping clearer are "unnecessary" only to |the compiler; almost nobody really has the C precedence rules memorized. Even more important, almost nobody has the C precedence rules internalized - memorized to the extent that reading an unparenthesised complex expression is easier than reading the same expression with careful (not necessarily total) parenthesisation. Many people will be able to internalize the precedence for addition and multiplication and (almost any single other operator) in a single expression and read such an expression at least as easily without parentheses. Such units make good candidates for the bottom level of parenthesisation within more complicated expressions. Extra parentheses beyond these may be appropriate also when an otherwise straightforward expression is long - either because of lengthy variable names or because the unary values are function calls with long arguments lists or other large expressions. -- sendmail - as easy to operate and as painless as using | John Macdonald manually powered dental tools on yourself - John R. MacMillan | jmm@eci386
sadkins@oucsace.cs.OHIOU.EDU (Scott W. Adkins) (04/09/91)
In article <1#.gqcm@rpi.edu> xor@aix01.aix.rpi.edu (Joseph Schwartz) writes: > >Is this true? The grammar in K&R1 (pg 218) does not require parens in the >return statement. However, the example on page 68 (and indeed all of the >examples in the book) show the parentheses around the expression. > When I learned C, I was taught that parens were unecessary, but it was highly recommended to use them for the same reason parens were to be used with macros (i.e. #define). I have used them ever since and have grown quite attached to them. Anymore, the program just would not look right if I leave the parens out. Oh well :-) >Another place I tend to see unnecessary parens is with the sizeof >operator. You can use "sizeof (typename)" or "sizeof expression"... >I often see "sizeof (expression)"...usually there's no space between >the sizeof and the left paren, which may reinforce the belief that >the parens "belong to" the sizeof operator. > Let us clarify the sizeof operator/function a little bit more. I cannot say that this is strictly K&R, because I can't. I do not have access to such manuals (or am too lazy to find out I have access to them). In many of the C books, particulary Microsoft, they make a distinction between the sizeof operator and the sizeof function. Unfortunatly, they do not mention the difference and do not tell you that parens are needed or not, they just use them. In some of the Turbo C books, a distinction is made and described very clearly. Quoting from "Using Turbo C" by Herbert Schildt, "Turbo C includes the compile-time operator called sizeof that returns the size of the variable of type that is its operand. The keyword sizeof precedes the operand's variable or type name. If sizeof operates on a data type, then the type must appear in parentheses." In this case, they do not indicate that one is a function and the other is an operator. Would someone please help me out here. Is this specific to IBM PC's or is it part of standard C? I am rather curious myself. I have always used the parens because I have never been quite sure when it was safe to not use them (although, now I do...). >Just curious...how often do you folks purposely insert unnecessary parens >into expressions? Sometimes I'll do it just to make the grouping clearer >(just in case the next person to read the code doesn't know all the >precedence rules by heart). I'm talking about expressions in general, >not just in conjunction with return or sizeof. > I use parens like they were going out of style. Another case that parens are more likely to be used, in my case anyway, is the shorthand conditional statements: variable = conditional ? then_part : else_part usually becomes something like: variable = (conditional ? (then_part) : (else_part)) ------------------------------------------------------------------------------- Scott W. Adkins Internet: sadkins@oucsace.cs.ohiou.edu ~~~~~~~~~~~~~~~ ak323@cleveland.freenet.edu (Flame me, not the net!) Bitnet: cs823@ouaccvmb.bitnet ------------------------------------------------------------------------------- You have seen the number of errors you get when writing your program. When you consider that the large quantity of your program is yet to be written, be very thankful that 90% of your errors are not in the part you have so far written.
boyne@hplvec.LVLD.HP.COM (Art Boyne) (04/09/91)
In comp.lang.c, darcy@druid.uucp (D'Arcy J.M. Cain) writes: > Whitespace doesn't add anything to the program either. Should we leave > that out as well? It is required in one case: "a=b/ *c". Without the space, we have the start of a comment, not a divide by the dereferenced pointer "c". Art Boyne, boyne@hplvla.hp.com
gwyn@smoke.brl.mil (Doug Gwyn) (04/16/91)
In article <3176@oucsace.cs.OHIOU.EDU> sadkins@oucsace.cs.OHIOU.EDU (Scott W. Adkins) writes: >In this case, they do not indicate that one is a function and the other is >an operator. sizeof is always a unary operator keyword, never a function name. It can be validly used in two distinct ways: sizeof unary_expression sizeof ( type_name ) Some people put parentheses around the innards of their unary_expression, but they are not required. (Same as for the operand of "return".)
steve@taumet.com (Stephen Clamage) (04/16/91)
sadkins@oucsace.cs.OHIOU.EDU (Scott W. Adkins) writes: >Let us clarify the sizeof operator/function a little bit more. I cannot >say that this is strictly K&R, because I can't.... >Quoting from "Using Turbo C" by Herbert Schildt, >"Turbo C includes the compile-time operator called sizeof that returns the >size of the variable of type that is its operand. The keyword sizeof precedes >the operand's variable or type name. If sizeof operates on a data type, then >the type must appear in parentheses." >In this case, they do not indicate that one is a function and the other is >an operator. Would someone please help me out here. Is this specific to >IBM PC's or is it part of standard C? In the ANSI C specification (section 3.3.3 and 3.3.3.4), sizeof is called a unary operator. Its operand is either a unary-expression or a type-name in parentheses. "unary-expression" and "type-name" are further defined elsewhere in the grammar. Among other kinds of expressions, any expression enclosed in parens is a unary-expression, so you can always use parens. For example: int i; char c; sizeof c + i /* A */ sizeof (c) + i /* B */ sizeof (c + i) /* C */ The values of A and B are the same, since sizeof operates on c. The result of sizeof on a char type is guaranteed to be 1 by the language. In C, however, the entire expression (c+i) is the operand of sizeof, the type of the expression is int, and the result of sizeof on an int is whatever the implementation says it is, typically 2 or 4. Now consider: sizeof(char) /* guaranteed to be 1 */ sizeof char /* syntax error */ sizeof( (int*)[10] ) /* array of 10 pointers to int */ For types, the parens are required as part of the syntax, independent of whatever parens the type description may require. -- Steve Clamage, TauMetric Corp, steve@taumet.com
ts@cup.portal.com (Tim W Smith) (04/18/91)
< sizeof( (int*)[10] ) /* array of 10 pointers to int */ Syntax error. Try sizeof( int *[10] ). Tim Smith
sarima@tdatirv.UUCP (Stanley Friesen) (04/20/91)
In article <3176@oucsace.cs.OHIOU.EDU> sadkins@oucsace.cs.OHIOU.EDU (Scott W. Adkins) writes:
< In many
<of the C books, particulary Microsoft, they make a distinction between
<the sizeof operator and the sizeof function. Unfortunatly, they do not
<mention the difference and do not tell you that parens are needed or not,
<they just use them.
These books are making a (very poor) attempt to explain what the Turbo C
books explain correctly below. They are *wrong*: sizeof is *always*
an operator, period.
[The idea is that a 'function' requires parens, but an 'operator' does not].
< In some of the Turbo C books, a distinction is made
<and described very clearly. Quoting from "Using Turbo C" by Herbert Schildt,
<
<"Turbo C includes the compile-time operator called sizeof that returns the
<size of the variable of type that is its operand. The keyword sizeof precedes
<the operand's variable or type name. If sizeof operates on a data type, then
<the type must appear in parentheses."
<
<In this case, they do not indicate that one is a function and the other is
<an operator. Would someone please help me out here.
Quite correctly, since there is no 'function sizeof'. What is happening here
is that the operator sizeof can take either an expression or a 'type cast'
as its argument (it is a unary operator). [Essentially an abstract type
name must be enclosed in parens anyewhere it is used.]
Thus the parens after a sizeof always belong to the argument *not* to
the operator.
< Is this specific to
<IBM PC's or is it part of standard C? I am rather curious myself. I have
<always used the parens because I have never been quite sure when it was safe
<to not use them (although, now I do...).
Turbo C is right, parens are only required around an abstract type name.
An expression may be used without any parens (but since any expression is
unchanged by adding parens they harm nothing).
I also use parens after all sizeof operators, more for readability than
for any other reason.
<I use parens like they were going out of style. Another case that parens are
<more likely to be used, in my case anyway, is the shorthand conditional
<statements:
<
< variable = conditional ? then_part : else_part
<
<usually becomes something like:
<
< variable = (conditional ? (then_part) : (else_part))
This is a little more than I usually do. However the outer parens are often
a good idea, since the precedence of ?: is so low.
--
---------------
uunet!tdatirv!sarima (Stanley Friesen)
browns@iccgcc.decnet.ab.com (Stan Brown) (04/20/91)
In article <3176@oucsace.cs.OHIOU.EDU>, sadkins@oucsace.cs.OHIOU.EDU (Scott W. Adkins) writes: > When I learned C, I was taught that parens were unecessary, but it was > highly recommended to use them for the same reason parens were to be used > with macros (i.e. #define). I have used them ever since and have grown > quite attached to them. Anymore, the program just would not look right > if I leave the parens out. Oh well :-) I'm afraid I don't see the analogy. You use parens around an expression in a macro because you don't know the context of the invocation of the macro. The expression in the return statement has no such problem. >>Another place I tend to see unnecessary parens is with the sizeof >>operator. You can use "sizeof (typename)" or "sizeof expression"... >>I often see "sizeof (expression)"...usually there's no space between >>the sizeof and the left paren, which may reinforce the belief that >>the parens "belong to" the sizeof operator. > Let us clarify the sizeof operator/function a little bit more. I cannot > say that this is strictly K&R, because I can't. I do not have access to > such manuals (or am too lazy to find out I have access to them). I wouldn't boast of this last if I were you. > In many > of the C books, particulary Microsoft, they make a distinction between > the sizeof operator and the sizeof function. You don't specify _which_ Microsoft, but this statement is false for both Microsoft C 5.0 and Microsoft C 5.1, and I'm willing to bet it's false for any other version. There is no sizeof 'function'. sizeof is an operator, pure and simple. As are other C operators, it is overloaded: its operand can be an object (or any other expression), or a type-cast (which is what the Microsoft C user's guide, v5.0, calls a type specifier in parentheses). Section 3.3.3.4 of the standard says, in part, "The sizeof operator yields the size (in bytes) of its operand, which may be an expression or the parenthesized name of a type." Stan Brown, Oak Road Systems, Cleveland, Ohio, USA +1 216 371 0043 email (until 91/4/30): browns@iccgcc.decnet.ab.com My opinions are mine: I don't speak for any other person or company.
mmcg@bruce.cs.monash.OZ.AU (Mike McGaughey) (04/20/91)
browns@iccgcc.decnet.ab.com (Stan Brown) writes: >In article <3176@oucsace.cs.OHIOU.EDU>, sadkins@oucsace.cs.OHIOU.EDU (Scott W. Adkins) writes: >> When I learned C, I was taught that parens were unecessary, but it was >> highly recommended to use them for the same reason parens were to be used >> with macros (i.e. #define). I have used them ever since and have grown >> quite attached to them. Anymore, the program just would not look right >> if I leave the parens out. Oh well :-) >I'm afraid I don't see the analogy. >You use parens around an expression in a macro because you don't know >the context of the invocation of the macro. The expression in the >return statement has no such problem. Oh, the point is just that if you stick to return(val) it makes it much simpler to #define return to be a macro, if you should ever have to do so (for instance, in printing a trace). Not that that's terribly useful, with a decent debugger. Mike. -- Mike McGaughey AARNET: mmcg@bruce.cs.monash.oz.au "His state is kingly; thousands at his bidding speed, And post o'er land and ocean without rest." - Milton.
marks@cbnewsl.att.com (mark.e.smith) (04/22/91)
In article <4003@bruce.cs.monash.OZ.AU> mmcg@bruce.cs.monash.OZ.AU (Mike McGaughey) writes: >browns@iccgcc.decnet.ab.com (Stan Brown) writes: > >>In article <3176@oucsace.cs.OHIOU.EDU>, sadkins@oucsace.cs.OHIOU.EDU (Scott W. Adkins) writes: >>> When I learned C, I was taught that parens were unecessary, but it was >>> highly recommended to use them for the same reason parens were to be used >>> with macros (i.e. #define). I have used them ever since and have grown >>> quite attached to them. Anymore, the program just would not look right >>> if I leave the parens out. Oh well :-) > >>I'm afraid I don't see the analogy. > >Oh, the point is just that if you stick to > > return(val) > >it makes it much simpler to #define return to be a macro, if you should >ever have to do so (for instance, in printing a trace). Not that >that's terribly useful, with a decent debugger. > >Mike McGaughey AARNET: mmcg@bruce.cs.monash.oz.au 'return' isn't a function, so it makes sense not to use it as such. However, I have upon occasion used a function Return( ret_val ) where Return() is a macro that restores scope. This can be used as a makeshift malloc()-free() monitor, complete with lovely setjmp()- longjmp()s. (The setjmp() and longjmp()s are also hidden in macros. In for a penny...) Now if we could only get the *language* to do this for us! Mark Smith