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