[comp.lang.c] Unnecessary parentheses

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