-----Non-member submission from [Will Adams <wadams@freescale.com>]----- Date: Wed, 02 Aug 2006 12:17:17 -0500 Whether the short-circuit evaluation of the logical operators in C is a mistake or not, this definition is well-entrenched and widely understood, and the same operators are used, with short-circuit semantics, in Unix shells (Bourne shell, C-shell, etc), Perl, Vera, and other languages. Optionally allowing these these operators to have non-short-circuit semantics requires different coding idioms. Optionally allowing short-circuit evaluation of arithmetic expressions seems to me to be a mistake, unless the conditions under which this is allowed are strengthened from the `same result' to the `same effect' (ie, the same result _and_ identical side-effects). A more general way to express this requirement is the `as if' rule, as in the C Standard. will Bresticker, Shalom wrote: > I won't take a position here on what the semantics in Verilog should > be, but I will note that generally, compatibility to C is not > necessarily always desirable. > > There have been cases where the C semantics have been considered > unfortunate (a misfeature), and in such cases, it is not necessarily > wise to continue to propagate what is considered to be a mistake. > > Shalom > >> -----Original Message----- >> From: Will Adams [mailto:wadams@freescale.com] >> Sent: Friday, July 28, 2006 11:15 PM >> 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] >> >> I agree that functions with side effects are a programming practice >> to be avoided. But the Standard itself requires the implementation of >> functions that have side effects (for example `$fgetc()'). Functions > can >> only be called in an expression context. A user would likely be >> surprised to discover (I know I was!) that the statement `b = >> $fgetc(fd) + a' is not guaranteed to read a character from file `fd'. >> >> The `contradictory desirable behaviors' that I describe are the > behavior >> shown by the C language for the syntax given. In C the operands of a >> logical operator are always evaluated left-to-right, stopping as soon > as >> the result is known; all operands of an arithmetic operator are >> evaluated, in any order. C has been in use for over 30 years, and its >> semantics are well known by a large community of programmers. >> >> I think it is unfortunate that Verilog uses the same operator symbols > as >> C, but allows them to be implemented with different semantics. It is >> particularly unfortunate that the change in semantics is optional, so >> users must be aware of all the different, legal, ways that a >> statement may be executed to fully understand if it will behave as >> they desire > on >> any Standard-conforming implementation. >> >> will >> >> >> Bresticker, Shalom wrote: >>> 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 Aug 2 10:40:06 2006
This archive was generated by hypermail 2.1.8 : Wed Aug 02 2006 - 10:40:12 PDT