[comp.lang.c] why bother with operator precedence

poser@csli.Stanford.EDU (Bill Poser) (03/27/90)

Insisting that students use minimal parenthesization will help them
to learn the precedence rules, but why bother? Students should of
course be familiar with the concept and with some very elementary
rules so that they will know what is going on when they read other people's
unparenthesized code, but it seems quite pointless to me to learn the
precedence table in detail. It is unnecessary, since you can always
parenthesize, it is tedious in a language like C with lots of operators
and precedence levels, and it is error prone, both in that it is easy
to make mistakes if one relies heavily on precedence and in that it
produces dangerous bad habits that don't port readily between languages.
Parenthesization (combined with line breaks and indentation) does a much
better job of displaying the structure of expressions.

So, why bother with precedence?

tongwu@ux.acs.umn.edu (Tong Wu) (03/27/90)

In article <12845@csli.Stanford.EDU> poser@csli.stanford.edu (Bill Poser) writes:
>Insisting that students use minimal parenthesization will help them
>......
>
>So, why bother with precedence?

An excellent point!  Using minimal parenthesization to achieve maximal use
of precedence rules is like not declearing variables, in Fortran, in order
to use the default variable types.

TW

glass@vixvax.mgi.com (William H. Glass) (03/27/90)

In article <12845@csli.Stanford.EDU>, poser@csli.Stanford.EDU (Bill Poser) writes:
> Insisting that students use minimal parenthesization will help them
> to learn the precedence rules, but why bother?

   I recall that in McCracken's 1960ish book on Fortran programming, he
said "when in doubt parenthesize".  I feel that is still good advice.  When
trying to debug someone else's code, I'd much rather see some extra
parenthesis then find a bug caused by someone who thought that he knew the
operator precedence, but didn't.

-- 

William H. Glass                        Internet: glass@mgi.com
Management Graphics, Inc.
1401 E. 79th Street
Minneapolis, MN  55425
+1 (612) 854-1220

tneff@bfmny0.UU.NET (Tom Neff) (03/27/90)

In article <2031@l.cc.purdue.edu> cik@l.cc.purdue.edu (Herman Rubin) writes:
>It is much worse.  The precedence rules in algebra are well known, but the
>arbitrary ones in C are not, and are not intuitive.  What is the precedence
>for 
>
>		a << b + c 

I think the point was that you should say what you mean, i.e.

		(a << b) + c
or
		a << (b + c)

as appropriate, in code that you write.  I try to do this myself in
cases where there might be any doubt among those who don't have
prefrontal YACC implants :-).

However it's probably a good idea to run C students through the list,
because they will someday have to READ code as well as write it.

It would also be nice to write and pass around a tiny public domain
utility that takes any C expression and parenthesizes it to the max.
-- 
"How can a man of integrity get along    ///  Tom Neff
in Washington?" -- Richard Feynman      ///   tneff@bfmny0.UU.NET

amull@Morgan.COM (Andrew P. Mullhaupt) (03/27/90)

I agree: there is no good reason to learn very much of the C precedence
table, and there are some good reasons not to. If you have to program
in more than one language on a daily basis, you just end up getting
annoyed at the idiomatic differences in expression evaluation, and you
end up skipping niceties like "do I need parentheses to separate boolean
clauses in a conditional?" and putting in parentheses because they are
universal. This might be coding for some kind of lowest common denominator
but anything else is exposed to some kind of risk. 

When you find someone else's code which relies on precedence to compress
many operations into one, you can pull apart the run-on expression
and form simple statements. Note: use of the 'short-circuit' booleans
and side-effects should be pulled apart into conditionals, or at least
formatted to reflect the flow of control. If you want to express a
multiple branch conditional you expect something like:

    if (C1) {
        S1;
    } else if (C2) {    /* separation of lines is used */
        S2;             /* to indicate flow of control */
        if (C3) {
            S3;
        }
    } else {
        S4;
    }

but when you have an assignment to a variable, you usually expect
something like:

    V =  Expression;    /* on one line if possible */

so when the two are combined (as some programmers often do in C)
what should the reader legitimately expect? You don't often see

    result = E1 || (fail_1_act, E2) || (fail_2_act, E3);

indented as:

    result = E1 ||
        (fail_1_act, E2) ||
            (fail_2_act, E3);

so unless you're out for the last drop of optimization you should use:

    if (E1) {                /* space is now available for */
        result = TRUE;       /* useful documentation */
    } else {
        fail_1_act;
        if (E2) {            /* for each branch */
            result = TRUE;
        } else {
            fail_2_act;
            result = E3;
        }
    }

and hope that your compiler knows enough to find common subexpressions
across the conditional statements. 

In the short-circuit boolean version, fail_1_act and fail_2_act are
likely to be evaluated for side effects. (What else is the role of
the comma operator?) Suppose that fail_1_act affects the value of the
expression E3. The effect of this action is more clearly expressed
in the last version.

Some might be tempted to use  "if (result=E1) ..." but there are some
unnecessary risks in this form. Replacing the "result = TRUE" statements
might convey an impression that code has been left out. 

I think this example points out how reliance on side effects and use
of precedence in the C language (which are common practices) lead to
unnecessary puzzles in reading C source. Some C programmers may know
enough to correctly practice minimal parenthesis code, but some other
programmers know enough not to bother with high-risk, low-reward code.

Later,
Andrew Mullhaupt

 

cik@l.cc.purdue.edu (Herman Rubin) (03/28/90)

In article <1379@ux.acs.umn.edu>, tongwu@ux.acs.umn.edu (Tong Wu) writes:
> In article <12845@csli.Stanford.EDU> poser@csli.stanford.edu (Bill Poser) writes:
< >Insisting that students use minimal parenthesization will help them
< >......
< >
< >So, why bother with precedence?
 
> An excellent point!  Using minimal parenthesization to achieve maximal use
> of precedence rules is like not declearing variables, in Fortran, in order
> to use the default variable types.
 

It is much worse.  The precedence rules in algebra are well known, but the
arbitrary ones in C are not, and are not intuitive.  What is the precedence
for 

		a << b + c 

-- 
Herman Rubin, Dept. of Statistics, Purdue Univ., West Lafayette IN47907
Phone: (317)494-6054
hrubin@l.cc.purdue.edu (Internet, bitnet, UUCP)

eric@snark.uu.net (Eric S. Raymond) (03/28/90)

In <12845@csli.Stanford.EDU> Bill Poser wrote:
> So, why bother with precedence?

I'll second your point and add that I think most expert C programmers use
parens rather than relying on precedence much beyond "* binds tighter than +"
and the fact that relationals bind tighter than && and ||. Myself, I wouldn't
have more than a vague idea of the hairier precedence/associativity rules
without looking at a chart, nor have I ever felt pressured to learn; parens
are cheap and give one that wonderful feeling of security.

Code defensively...the life you save may be your own!
-- 
      Eric S. Raymond = eric@snark.uu.net    (mad mastermind of TMN-Netnews)

cjoslyn@bingvaxu.cc.binghamton.edu (Cliff Joslyn) (03/28/90)

Since operator precedence in C is relatively arbitrary and there are
*many* operators, I let my students use an operator chart on exams
(along with an ASCII chart and other similar collections of detailed
information that no one should need to memorize).  Then I might give
them one of the monster expressions we've seen and ask them to provide a
parsing, along with an evalution of the type, size, and value of each
sub-expression.  In code, I criticize both over-parenthesization and
under-parenthesization as I see fit.  This seems to accomplish both ends
of teaching precedence while not being dogmatic about it. 

-- 
O------------------------------------------------------------------------->
| Cliff Joslyn, Cybernetician at Large, cjoslyn@bingvaxu.cc.binghamton.edu
| Systems Science, SUNY Binghamton, Box 1070, Binghamton NY 13901, USA
V All the world is biscuit shaped. . .

emuleomo@paul.rutgers.edu (Emuleomo) (03/29/90)

This is why people say that C code is *hard* to read!
Why say 
 a = b >> 4 + 5;
when you can say
 a = b >> (4 + 5);

Even DMR may have to dive into his manual once in a while if he sees the
former expression, but a C neophyte fully understands what the latter does!
Well I guess the former is why we have masochists in society!


--Emuleomo O.O. (emuleomo@yes.rutgers.edu)
-- 
*Nothing* is hard.   If it looks hard, you are looking at it the hard way!

jk@hpfelg.HP.COM (John Kessenich) (03/29/90)

>Insisting that students use minimal parenthesization will help them
>to learn the precedence rules, but why bother?

Completely paranthesizing a complex expression makes it unreadable,
but partial paranthesization mixed with vague knowledge of precedence 
leads to errors (if you're not going to put all paranthesis on, and 
you're not sure of the rules, the ones you leave out are potentially 
incorrect guesses).

Best choice: have detailed knowledge of precedence but paranthesize 
for correctness and readability instead of minimality.

--------------
John Kessenich