-----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. willReceived on Tue Jul 25 11:20:16 2006
This archive was generated by hypermail 2.1.8 : Tue Jul 25 2006 - 11:20:35 PDT