john@viper.UUCP (03/04/87)
I made an incorrect statement a few days ago in this newsgroup about the order of evaluation of a series of additions where parens were included. The message I was disagreeing with stated that the parens have no effect on the structure of the evaluation tree generated. Since then, I've received a few messages pointing out references in K&R which explicitly state that the elements in a series of additions (or multiplications) may freely be reordered to occur in any order by the compiler. I sit corrected, but I still feel that the standard should have rules which will allow a programmer to -know- the exact order of evaluation for any equation. I know this is not likely for the sole reason that there are too many different compilers already existing that do the ordering in far too many different ways.... I still feel that this is a significant failing in the language definition and would like to see a change. --- John Stanley (john@viper.UUCP) Software Consultant - DynaSoft Systems UUCP: ...{amdahl,ihnp4,rutgers}!{meccts,dayton}!viper!john
tps@sdchem.UUCP (Tom Stockfisch) (03/07/87)
In article <616@viper.UUCP> john@viper.UUCP (John Stanley) writes: >... but I still feel that the standard should have rules >which will allow a programmer to -know- the exact order of evaluation for >any equation. I know this is not likely for the sole reason that there >are too many different compilers already existing that do the ordering in >far too many different ways.... I still feel that this is a significant >failing in the language definition and would like to see a change. >John Stanley (john@viper.UUCP) I feel this is a significant *feature* of the language. This issue has been discussed recently, but I would like to summarize the pluses of allowing expression rearrangement. Most of the ideas below were contributed by others, and thats all the more specific credit I can give since I didn't save any of the postings. 1. Most of the time, unless you are writing for one particular machine, the compiler knows better in what order to perform operations, since that order is machine-dependent. An important feature of C is that not only is the correctness of a program portable among many machines, but usually its efficiency as well. The local compiler chooses the method best for the local machine to implement your algorithm. 2. You can write expressions in a way that best documents them for and explains them to other human readers. 3. If you have complex multiple side effects in the same expression, you deserve what you get. 4. There are two mechanisms available for when you really need to know the order: 1) Separate the expression into two statements. 2) Use the unary plus operator (when you get your ANSI compiler). 5. If you want everything evaluated strictly from left to right, your thinking is too linear. What are you are proposing is to remove an important feature that can't be gotten at any other way. Reliable execution order can be forced when you really need it. If we drop the rearrangement feature there is no way to tell the compiler "I don't care how you do it, just get it done, hopefully using the methods best for the machine on which you exist." C currently provides both features, and since the "I don't care how..." one is by far the more common one, it is very appropriately the default. Who wants a language with fewer features (besides Ada users)? Finally, if you were to remove this feature, there would be no way to get it back. || Tom Stockfisch, UCSD Chemistry tps%chem@sdcsvax.UCSD
flaps@utcsri.UUCP (Alan J Rosenthal) (03/08/87)
In article <616@viper.UUCP> john@viper.UUCP (John Stanley) writes: >I still feel that the standard should have rules >which will allow a programmer to -know- the exact order of evaluation for >any equation. It does.. use temporaries. For example, if you want the sum a+b+c evaluated in the order implied by (a+b)+c, simply write two statements, the first of which is t=a+b; and the second of which contains the expression t+c. (If you have a REALLY good optimizer it's possible that this temporary variable will be optimized out completely. In any case, the redundant store/load will probably be optimized out.) >I know this is not likely for the sole reason that there >are too many different compilers already existing that do the ordering in >far too many different ways. Also for the reason that there is quite likely a different best order for different machines, so the compilers should be free to implement the best order for their machine. -- Alan J Rosenthal UUCP: {backbone}!seismo!mnetor!utgpu!flaps, ubc-vision!utai!utgpu!flaps, or utzoo!utgpu!flaps (among other possibilities) ARPA: flaps@csri.toronto.edu CSNET: flaps@toronto BITNET: flaps at utorgpu
chris@mimsy.UUCP (03/25/87)
In article <739@xanth.UUCP> kent@xanth.UUCP (Kent Paul Dolan) writes: >... but C was an ugly language to begin with, because so much of >it doesn't parse the way it reads, due to _bizarre_ precedence results. Aside from the results of chongo's contests, I find most C code quite readable. The trouble areas are unusual declarations and `&' and `|' precedence: char *(*p[3])(); ... if (a & 1 == 0) /* is not what you expected */ The solution to the latter, of course, is (dramatic music) to Put In Many Many Parentheses. >Adding the unary plus, which, to anyone taught mathematics, >is a no-op, and making that the way to control the order of >evaluation, just makes an ugly language uglier. While it is a bit of a kludge, the fact that someone has written an explicit no-op should give you a hint that something special is going on. >ANSI should have mandated respecting parentheses for evaluation >order, so that code executes the way it reads. I do not agree. >This would break _no_ code, True enough. >and would let programmers' intuition be of some use .... Whose intuition? Certainly not mine. I expect the compiler to rip my parentheses to shreds. I confess to having written some floating point code in the past, aye, even in FORTRAN. I used multiple lines of statments to control evaluation order---even in FORTRAN, and even before I knew any other language except BASIC. (A humble start indeed!) #define input() \ ((env->c = getc(fin)) == '\n' ? \ (env->lineno++, env->c) : env->c) #define output(c) \ (putc(c, env->fout), ferror(env->fout) ? ioerr() : 0) output(input()) produces ((--(env->fout)->_cnt>=0? (int)(*(unsigned char*)(env->fout)->_ptr++=(((env->c=(--(fin)->_cnt>=0? (int)(*(unsigned char*)(fin)->_ptr++):_filbuf(fin)))=='\n'? (env->lineno++,env->c):env->c))): (((env->fout)->_flag&0200)&&-(env->fout)->_cnt<(env->fout)->_bufsiz? ((*(env->fout)->_ptr=(((env->c=(--(fin)->_cnt>=0? (int)(*(unsigned char*)(fin)->_ptr++):_filbuf(fin)))=='\n'? (env->lineno++,env->c):env->c)))!='\n'? (int)(*(unsigned char*)(env->fout)->_ptr++): _flsbuf(*(unsigned char*)(env->fout)->_ptr,env->fout)): _flsbuf((unsigned char)(((env->c=(--(fin)->_cnt>=0? (int)(*(unsigned char*)(fin)->_ptr++):_filbuf(fin)))=='\n'? (env->lineno++,env->c):env->c)),env->fout))), (((env->fout)->_flag&040)!=0)?ioerr():0) Ahh, lovely parentheses. :-) -- In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690) UUCP: seismo!mimsy!chris ARPA/CSNet: chris@mimsy.umd.edu
mouse@mcgill-vision.UUCP (der Mouse) (08/20/89)
In article <1989Aug9.094742.20000@gdt.bath.ac.uk>, exspes@gdr.bath.ac.uk (P E Smee) writes: > (Although, being paranoid, I'd also suggest that the person writing > a/b/c/d/e should inject lots of ()s to indicate that the ordering is > really desired. I tend to parenthesize everything :-) Goes without > saying that I strongly feel that languages should honor any > order-of-evaluation requirements which the programmer specifies using > parens. I agree. The problem is telling order-of-evaluation-requirements parens from override-operator-precedence parens. A high percentage (most?) of the parentheses I use, for example, are either required syntax (as in a while loop), which don't enter into this discussion, or needed not because order of evaluation is important but to override default operator precedence and associativity rules. Then there are macros. #define islower(c) (__ctypes[(c)+1]&__CTYPE_LOWER) #define TABLE_FOR(c) (islower(c)?ltab:utab) .... a_table = TABLE_FOR('a'+letindex); (Let's ignore the ASCII-dependent nature of that for the moment.) I would be most disappointed in any compiler that failed to constant-merge the 'a' and the 1 simply because the expanded text, which would read something like a_table = ((__ctypes[('a'+letindex)+1]&__CTYPE_LOWER)?ltab:utab); happens to have a pair of parens which contain the 'a' but not the 1, thereby prohibiting rearrangement to bring the 'a' and 1 together. Yet if we omit that pair of parens in the definition of islower, it then loses big if we write, for example, islower(usec1?c1:c2) which would then expand to (__ctypes[usec1?c1:c2+1]&__CTYPE_LOWER) ...oops. der Mouse old: mcgill-vision!mouse new: mouse@larry.mcrcim.mcgill.edu (Curious. Put "islower" next to "isupper" and it reads one way; put it next to "jslower" and "kslower" and it reads entirely differently. :-)