Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!utgpu!water!watnot!watmath!clyde!cbatt!ihnp4!ptsfa!lll-lcc!seismo!mcvax!ukc!icdoc!cl-jenny!am From: am@cl-jenny.UUCP Newsgroups: comp.lang.c Subject: Legal re-arrangement rules. Why they seem inconsistent. Message-ID: <681@jenny.cl.cam.ac.uk> Date: Wed, 11-Mar-87 05:57:50 EST Article-I.D.: jenny.681 Posted: Wed Mar 11 05:57:50 1987 Date-Received: Fri, 13-Mar-87 07:04:52 EST References: <844@wanginst.EDU> <4211@utcsri.UUCP> <609@viper.UUCP> <4315@utcsri.UUCP> Reply-To: am@cl.cam.ac.uk (Alan Mycroft) Organization: U of Cambridge Comp Lab, UK Lines: 55 Keywords: associative commutative operations. Summary: The re-assocation rules are at best arbitrary, often not identities and do not allow rearrangement that many users expect to be allowed. Sorry to pick on your message, but there are several points to be observed and some appear in your article. The gist is that re-arrangement in ANSI (and K&R) seems badly thought out (just echoes of some long lost (or current!) C compiler does) and not what really makes sense... In article <4315@utcsri.UUCP> you write: >I want my compiler to be free to change (i+3)*4+6 >to i*4+18 (more on this later). If I don't want that, there are means >of avoiding it. I'm afraid neither ANSI nor K&R sanction this particular transformation. They allow re-arrangement of associative operators. Nothing is said about your wish that mathematical 'distributive' laws are applicable. In particular, were (e.g. i = 0x8000000) i*4 to overflow but (i+3)*4 not to do and the compiler to signal on signed overflow as the standard permits then this transformation is INVALID and a compiler which did it not conforming. Of course, if signed overflow is ignored on a two's complement machine then this transformation IS again valid, but by appeal to the 'as if' principle - not the re-association rules. >It allows constants to be folded to the end (a+2)+(b+9)+4 = (a+b)+15. 1.I disagree in principle that ANSI and K&R ought to allow this transformation if a & b are floating. Consider a=1e30, b=-1e30. Then the transformation is sanctioned but the two sides of this 'equality' probably reduce to 4 and 15. Just because one compiler in the past did it.... 2.Anyway, even if we concede that the spec. will/does allow this, we find that it can re-arrange ch+(-'a')+'A' but not the more natural ch-'a'+'A'. (Nothing is said about re-arranging thing with '-' in -- it is not assocative or commutative). >Multiple constants in running sums tend to pop up (1) from macro >expansions (2) in expressions like (p+3)->foo.y[i-1].abc ( after the >semantics have been applied ). But there is only one '+' in here so the compiler can't re-arrange it. (Ansi is unclear whether the '+' introduced by e1[e2] can be re-arranged - probably not since + on pointers is NOT assocative for type reasons). Certainly the + introduced by component selection is not re-arrangeable. >And once you convert arbitrary additions into rearrangable running sums, >it becomes very attractive to convert things like (i+7)*4 + 2 into >i*4 + 28 + 2 into i*4 + 30. Again, this comes up a *lot* with array >operations, and again, if it breaks a program, that program was probably >doomed anyway. Again, the spec. is unclear about whether multiple array subscripts can be folded/re-arranged. They typically involve + and * and as I said above such re-arrangement is forbidden. Now, what you have written is probably current in many compilers (and probably valid provided they are two's complement and never signal overflow). But the points I am trying to make are that ANSI/K&R do no allow them and that the re-arrangement rules seem inherently ill-thought out. Alan Mycroft