RE: [sv-bc] [Fwd: Issues with IEEE 1364-2005]

From: Bresticker, Shalom <shalom.bresticker_at_.....>
Date: Wed Jul 26 2006 - 22:39:35 PDT
Side-effects are in general an undesirable programming practice.

Will's two examples produce two contradictory desirable behaviors:

In the example "p != null && p.data > 0", one would desire that the
expression be short-circuited.

On the other hand, in the expression "f( ) + a", one would normally want
the side-effect to occur regardless of a, especially because most users
don't even know that short-circuiting can occur.

I do agree that the description of the condition evaluation in 5.1.13
appears to be reversed.

Shalom

> -----Original Message-----
> From: owner-sv-bc@server.eda-stds.org [mailto:owner-sv-bc@server.eda-
> stds.org] On Behalf Of Brad Pierce
> Sent: Wednesday, July 26, 2006 8:13 PM
> To: Will Adams
> Cc: sv-bc@server.eda-stds.org; michael.burns@freescale.com
> Subject: RE: [sv-bc] [Fwd: Issues with IEEE 1364-2005]
> 
> See also --
> 
>     http://www.boyd.com/1364_btf/report/full_pr/449.html
>     http://www.boyd.com/1364_btf/report/full_pr/288.html
> 
> -- Brad
> 
> -----Original Message-----
> From: Will Adams [mailto:wadams@freescale.com]
> Sent: Wednesday, July 26, 2006 9:31 AM
> To: Bresticker, Shalom
> Cc: Brad Pierce; sv-bc@eda-stds.org; michael.burns@freescale.com
> Subject: Re: [sv-bc] [Fwd: Issues with IEEE 1364-2005]
> 
> On the evaluation of the conditional operator, IEEE 1364-2005, section
> 5.1.13 `Conditional operator', states the following.
> 
>    conditional_expression ::= (From A.8.3)
>      expression1 ? { attribute_instance } expression2 : expression3
>    expression1 ::= expression
>    expression2 ::= expression
>    expression3 ::= expression
> 
>    The evaluation of a conditional operator shall begin with a logical
>    equality comparison (see 5.1.8) of expression1 with zero, termed
the
>    condition. If the condition evaluates to false (0), then
expression3
>    shall be evaluated and used as the result of the conditional
>    expression. If the condition evaluates to true (1), then
expression2
>    is evaluated and used as the result. If the condition evaluates to
an
>    ambiguous value (x or z), then both expression2 and expression3
shall
>    be evaluated; and their results shall be combined, bit by bit,
using
>    Table 5-21 to calculate the final result unless expression2 or
>    expression3 is real, in which case the result shall be 0.
> 
> I am not sure why this defines `condition' as `a logical equality
> comparison of expression1 with zero', since this means that
`condition'
> is the negation of `expression1' (`expression1 == 0' is 1 when
> `expression1' is 0, 0 when it is 1, and X when it is X or Z), and,
> applying the rest of the definition, when `expression1' is 1,
> `condition' is 0, and so `expression3' is evaluated as the result of
the
> conditional expression. Similarly, if `expression1' is 0, then
> `expression2' is evaluated as the result of the conditional
expression.
> This seems to give the semantics of an `if else then' operator, rather
> than an `if then else', which I doubt is what is intended.
> 
> Regardless, it does state that `expression1' must be evaluated first,
> and only one of `expression2' and `expression3' is evaluated when
> `condition' is 1 or 0, and both are evaluated when `condition' is X or
> Z. It also clearly states that evaluation of the conditional operator
> `shall begin with' the evaluation of the condition, and only after
this
> is evaluated does it start evaluating `expression2' or `expression3'.
> 
> Given this, my question about the order of evaluation of the two
> conditional operators in `a ? b : c ? d : e' remains. In cases where
the
> right-hand conditional operator is evaluated, the evaluation of the
> left-hand conditional operator begins before, and ends after, the
> evaluation of the right-hand operator, so in what sense is this
> right-to-left evaluation of the operators?
> 
> There is, in my mind, a problem with the statement in section 5.1.4,
> `However, if the final result of an expression can be determined
early,
> the entire expression need not be evaluated.' This refers only to the
> _result_ of an expression, and not to any side-effects, which leaves
us
> in a position where side-effects of potentially unevaluated arguments
> may or may not occur. This in turn requires excessively careful coding
> to avoid code that may give different results on different
> Standard-conforming implementations.
> 
> If this section is read strictly, then we must write code as though
all
> operands may be evaluated, and may not be if other operands are
> sufficient to determine the result of the expression. Thus my example
> `p != null && p.data > 0' is illegal, since `p.data' is illegal when
`p'
> is null, and a Standard-conforming implementation may evaluate the
> second operand when `p' is null. (We can, of course, rewrite this as
> `p != null ? p.data > 0 : 0', to give an expression that is guaranteed
> not to evaluate `p.data' when `p' is null.)
> 
> Also, we should never write `f( ) + a' if function call `f( )' has a
> side-effect, because a Standard-conforming implementation may choose
not
> to evaluate the first operand if `a' evaluates to X (and thus the
result
> of the expression is X, regardless of the value of `f( )').
> 
> My preference is for a rule that mandates which operands are
evaluated,
> and in which order (where this is important), together with a rule
> similar to the `as if' rule of the C standard, which allows
> implementations to break the rules as long as the observable effect is
> as if they had been followed. So, for example, if the rule is that all
> operands in an arithmetic expression must be evaluated, using the `as
> if' rule, an implementation is allowed not to evaluate `a' in `a + X'
> provided that it can determine that the evaluation of `a' has no
> observable side-effects.
> 
> will adams
> 
> 
> Bresticker, Shalom wrote:
> 
> > 1. As Brad points out, 1364 does relate to short-circuiting by
saying
> >  that an implementation may optionally implement short-circuiting,
> > but is not required to do so.
> >
> > 2. In the given example,
> >> a ? b : c ? d : e
> > which is parsed as
> >> a ? b : ( c ? d : e )
> >
> > Will says, " If `a' is 1, then the RH `?:' operator is not
evaluated"
> >  .
> >
> > That is not at all clear. Will himself says, " The operand
evaluation
> >  order only really needs to be defined
> >> when the result of evaluating one operand affects how the remaining
> >>  operands are evaluated."
> >
> > I don't know what implementations actually do. But at least in most
> > cases, there is no problem in principle in defining that the second
> > ?: is evaluated first. If an implementation optimizes by identifying
> > that it is unnecessary, that is not a problem as long as it does not
> > change the result.
> >
> > Shalom
> >
> >
> >
> >> -----Original Message----- From: owner-sv-bc@server.eda-stds.org
> >> [mailto:owner-sv-bc@server.eda- stds.org] On Behalf Of Brad Pierce
> >>  Sent: Tuesday, July 25, 2006 9:26 PM To: sv-bc@server.eda-stds.org
> >>  Cc: michael.burns@freescale.com; WADAMS@freescale.com Subject: Re:
> >>  [sv-bc] [Fwd: Issues with IEEE 1364-2005]
> >>
> >> See http://www.eda-stds.org/sv-ac/hm/2501.html .
> >>
> >> -- Brad
> >>
> >> -----Original Message----- From: owner-sv-bc@eda-stds.org
> >> [mailto:owner-sv-bc@eda-stds.org] On Behalf Of Brad Pierce Sent:
> >> Tuesday, July 25, 2006 11:20 AM To: sv-bc@eda-stds.org Cc:
> >> michael.burns@freescale.com; WADAMS@freescale.com Subject: [sv-bc]
> >> [Fwd: Issues with IEEE 1364-2005]
> >>
> >> -----Non-member submission-----
> >>
> >> Date: Tue, 25 Jul 2006 09:19:24 -0700 From: Michael Burns
> >> <michael.burns@freescale.com> CC: William Adams
> >> <WADAMS@freescale.com>
> >>
> >> Hi folks,
> >>
> >> A comment on precedence definitions in Verilog from one of our
> >> engineers.
> >>
> >> --Mike
> >>
> >> -------- Original Message -------- Subject: Issues with IEEE
> >> 1364-2005 Date: Mon, 24 Jul 2006 09:34:24 -0500 From: Will Adams
> >> <wadams@freescale.com> To: Michael Burns
> >> <michael.burns@freescale.com>
> >>
> >> There is a misstatement in the IEEE 1364-2005 standard, which has
> >> been there for a while (it was in 1364-2001, and perhaps in earlier
> >>  versions of the Standard). Do you know how to get it fixed?
> >>
> >> The error is in section 5.1.2 `Operator precedence'. There it
> >> states
> >>
> >> All operators shall associate left to right with the exception of
> > the
> >> conditional operator, which shall associate right to left.
> >> Associativity refers to the order in which the operators having the
> >>  same precedence are evaluated.
> >>
> >> This is wrong. It does not make a lot of sense to talk about `the
> > order
> >> in which operators ... are evaluated', since I do not think this is
> >>  well-defined in all circumstances (see below). What can be defined
> >>  is the order of _operand_ evaluation.
> >>
> >> This clause confuses associativity, which concerns the parsing of
> >> expressions that are not fully parenthesized, with evaluation
> >> order. I think what this may be getting at is that if `a + b + c'
> >> is parsed as `(a + b) + c', then the LH `+' operator is evaluated
> >> before the RH `+' operator, since subexpression must be evaluated
> >> before a containing expression. This definition fails to adequately
> >>  describe the intended evaluation of the conditional operator,
> >> which associates
> > right-to-left,
> >> but whose operands are evaluated left-to-right.
> >>
> >> The right-to-left associativity of the conditional operator means
> >> that the expression
> >>
> >> a ? b : c ? d : e
> >>
> >> is parsed as
> >>
> >> a ? b : ( c ? d : e )
> >>
> >> and not as
> >>
> >> ( a ? b : c ) ? d : e
> >>
> >> This is the same as in C, and allows the writing of `if ... else if
> >>
> >>
> > ...
> >> else ...' constructs using the conditional operator without
> >> excessive parentheses.
> >>
> >> However, the conditional operator is evaluated left-to-right. First
> >>
> >>
> > the
> >> condition is evaluated, and then one or both branches is evaluated.
> >>
> >>
> >>
> >> To see that the order of _operator_ evaluation is not always well
> >> defined, consider the evaluation of this expression. Operand `a'
> > (which
> >> is an operand of the LH `?:' operator) is evaluated first. If `a'
> >> is
> > 1,
> >> then the RH `?:' operator is not evaluated; if `a' is 0, then the
> > `else'
> >> expression (ie, `c ? d : e') is evaluated, and its value is the
> >> value
> > of
> >> the whole expression (ie, of the LH `?:' operator); and if `a' is X
> >>  or Z, then the RH `?:' is evaluated, and its result is combined
> >> bitwise with the result of evaluating `b' to yield the overall
> >> result of the whole expression. So, in cases where the RH `?:'
> >> operator is
> > evaluated,
> >> the evaluation of the LH `?:' operator begins before, and ends
> >> after, the evaluation of the RH `?:' operator. So what is the
> >> operator evaluation order?
> >>
> >> I have seen similar mistakes in several C++ textbooks. As far as I
> >> can tell, it is necessary to have three concepts to clearly define
> >> how expressions are parsed and evaluated: precedence,
> >> associativity, and operand evaluation order. The first two together
> >>  allow the
> > construction
> >> of a unique parse tree for any expression, and the third then
> >> mandates how this parse tree is to be evaluated.
> >>
> >> For most operators, there should be no operand evaluation order.
> >> For
> > the
> >> expression `a + b', an implementor should be free to evaluate `a'
> > first,
> >> `b' first, or both simultaneously, and they should be free to
> >> choose a different order each time the expression is evaluated, if
> >> it suits
> > them
> >> to do so. The operand evaluation order only really needs to be
> >> defined when the result of evaluating one operand affects how the
> >> remaining operands are evaluated (the only exception to this I can
> >> think of is
> > the
> >> `,' sequencing operator in C).
> >>
> >> On a related issue, Section 5.1.9 `Logical operators' does not
> >> state
> > if
> >> `&&' and `||' are evaluated in a short-circuit fashion, as they are
> >>  in C. That is, for the C expression `a && b', `a' is evaluated
> >> first,
> > and,
> >> if it is 0, `b' is not evaluated, since the value of the expression
> >>  is
> > 0
> >> regardless of the value of `b'. If this is not the case, then
> > different
> >> coding idioms are required. In C, to test if integer pointer `p' is
> >>  non-null, and points to a positive value, we write `p != 0 && *p >
> >>  0'. This never leads to segfault, since `p' is not dereferenced if
> >>  it is null. An equivalent expression in SystemVerilog, `p != null
> >> && p->data > 0' will cause a null object access error if
> > both
> >> operands are evaluated when `p' is null.
> >>
> >> Keeping the concepts of associativity and evaluation order separate
> >>  allows for a clearer statement of the requirements. We can
> >> distinguish `&&', which associates left-to-right, and whose
> >> operands (I am
> > assuming)
> >> are evaluated left-to-right, from `+', which associates
> >> left-to-right, but has no required evaluation order. Operator `?:'
> >> associates right-to-left, and evaluates left-to-right.
> >>
> >> I appreciate that these are minor issues, but I think the Standard
> >>  should be fixed to precisely define the requirements on
> >> implementors.
> >>
> >> will
> >
Received on Wed Jul 26 22:39:54 2006

This archive was generated by hypermail 2.1.8 : Wed Jul 26 2006 - 22:40:00 PDT