Disclaimer: I am not an expert, did not write CIL (neither gcc ;-), so what follows is nothing more than my humble understanding of C99.
On Fri, Aug 28, 2009 at 06:00:40PM +0200, Enea Zaffanella wrote: > I was considering the second example sent by Roberto. > Here we need to evaluate the following: > > a = ((*p[0]->next) += 1); > > in a state where the subexpression > *p[0]->next > evaluates to > p[0]. > > So the statement above modifies objects 'a' and 'p[0]', > which are distinct. > Moreover, the *old* value of object 'p[0]' is read (only once) > and it is only used to compute the *new* value that has to be stored > into object 'p[0]'. > > So I cannot see the undefined behavior mentioned in C99 6.5-2: > ===== > 2 Between the previous and next sequence point an object shall have its > stored value modified at most once by the evaluation of an expression. > Furthermore, the prior value shall be read only to determine the value > to be stored. > ===== > > To my eyes, this is exactly the same as > > p[0] = p[0] + 1; > > Am I missing something? I'm not an expert, but the spec says an object is a "region of data storage in the execution environment, the contents of which can represent values" (3.14), so basically this is a segment of memory (and has few to do with symbolic variables from the original program). In this example, I think the object accessed via p[0] is NOT "read only to determine the value to be stored". It is also read to determine the value of *p[0]->next, to evaluate it to p[0], that is to determine where to store it. (This doesn't sound very convincing.) The fact that ++x is syntactic sugar for x += 1, and that += does evaluate it's left operand only once (so, this is NOT equivalent to x = x + 1) must also be important in that case (but I'm not sure what it means). On the other hand, I'm not sure CIL respects the "optimization rules for factoring out assignments" stated in the Rationale (6.5.16). I'm a bit lost here, to be perfectly honnest. And, further, the Rationale is not normative anyway... E.g., the above expression can be rewritten: a = ( t = (*p[0]->next), (*p[0]->next) = (*p[0]->next) + 1, t + 1 ); following the first rule, or a = ( t = (*p[0]->next) + 1, (*p[0]->next) = (*p[0]->next) + 1, t ); following the second rule (unless the "provided that neither i nor y have side effects themselves" provision is not met, but I don't see why they would have side effects). This is very deterministic, coherent with gcc, but not with CIL. Anyone else? -- Gabriel Kerneis ------------------------------------------------------------------------------ Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day trial. Simplify your report design, integration and deployment - and focus on what you do best, core application coding. Discover what's new with Crystal Reports now. http://p.sf.net/sfu/bobj-july _______________________________________________ CIL-users mailing list CIL-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/cil-users