ggs@ulysses.homer.nj.att.com (Griff Smith) (09/25/87)
A user of our system grumbled recently that our C compiler is broken. He tried to compile the following on our 4.3BSD CCI POWER 6/32 C compiler: int j = ((int )(.5 * 4)); The response from the compiler was "foo.c", line 1: illegal initialization I then wrapped a function around it and compiled it on a 4.3BSD VAX and on the 4.3BSD tahoe compiler. The VAX produced the following assembly language fragment: movl $2,-4(fp) # 0.5 * 4 has been reduced to 2 movl -4(fp),r0 ret The tahoe did it the hard way: .data .align 2 L20: .long 0x41000000, 0x00000000 # .double 2 .text ldd L20 # note that .5 * 4 is reduced to 2.0 cvdl r0 # convert to long the hard way movl r0,-56(fp) movl -56(fp),r0 ret#1 I think this explains the problem with constant initialization on the tahoe compiler; the expression is "too complex". I also tried the 4.2BSD VAX C compiler and got output similar to the tahoe. The question is - what is a reasonable level of constant folding that I can assume when trying to write portable code? Is this a bug or a gotcha? K&R says that I can have almost any set of constants connected by +, -, *, ?: and a host of others (page 211). -- Griff Smith AT&T (Bell Laboratories), Murray Hill Phone: 1-201-582-7736 UUCP: {allegra|ihnp4}!ulysses!ggs Internet: ggs@ulysses.uucp
guy%gorodish@Sun.COM (Guy Harris) (09/26/87)
> The question is - what is a reasonable level of constant folding that > I can assume when trying to write portable code? Is this a bug or a > gotcha? This is a bug. Any reasonable and correct compiler will certainly include float -> int conversions, and *vice versa*, as operations that can be performed at compile time, as well as the usual sorts of floating-point and integer operations. The trouble is that PCC's code for doing folding of conversions of constants at compile time is very fragile, and if you don't arrange to have things done at the proper times, PCC ends up seeing trees with conversion operators, rather than constants, at the root and gets all ticked off at you. I have seen this sort of thing break several flavors of PCC (including CCI's 68K compiler; that one I fixed, for at least some of the cases). Unfortunately, fixes to one version may not fix other versions; some of the code in question lives in the machine-dependent portions of PCC. Guy Harris {ihnp4, decvax, seismo, decwrl, ...}!sun!guy guy@sun.c);g
gwyn@brl-smoke.ARPA (Doug Gwyn ) (09/27/87)
In article <3018@ulysses.homer.nj.att.com> ggs@ulysses.homer.nj.att.com (Griff Smith) writes: >The question is - what is a reasonable level of constant folding that >I can assume when trying to write portable code? The practical answer is, if you need to anticipate the actual behavior of a wide range of existing C compilers, you cannot count on very much! Generally, constant expressions involving just integers and the simple arithmetic operations are handled correctly by C compilers. Constant expressions involving much more, for example floating-point and casts, are only handled correctly by some implementations, although the forthcoming C standard promises that they are valid in initializers.
henry@utzoo.UUCP (Henry Spencer) (09/29/87)
> The question is - what is a reasonable level of constant folding that > I can assume when trying to write portable code? ... Well, read X3J11's latest draft for what you *ought* to be able to assume. Now, in reality: 1. Keep It Simple. Keep It Simple. Keep It Simple. 2. Casts were a late addition to the language and to some compilers; expect trouble there. 3. Compile-time floating-point evaluation is another dangerous area, especially in cross-compilers. -- "There's a lot more to do in space | Henry Spencer @ U of Toronto Zoology than sending people to Mars." --Bova | {allegra,ihnp4,decvax,utai}!utzoo!henry