Newsgroups: comp.std.c Path: utzoo!henry From: henry@zoo.toronto.edu (Henry Spencer) Subject: Re: Strange behaviour with old-style code Message-ID: <1991Feb10.004728.256@zoo.toronto.edu> Organization: U of Toronto Zoology References: <1991Feb6.190607.11731@alias.uucp> Date: Sun, 10 Feb 1991 00:47:28 GMT In article <1991Feb6.190607.11731@alias.uucp> rsargent@alias.UUCP (Richard Sargent) writes: >The compiler passes floats widened to doubles, and the routine pulls >the values off the stack using the appropriate widened addressing, >but then proceeds to use the "declared" argument type to do single >precision floating point arithmetic... This is correct. Only arrays and functions have their types silently rewritten in function declarations. Note 3.7.1: "On entry to the function the value of each argument expression shall be converted to the type of its corresponding parameter, as if by assignment..." So an old-style function, absent prototypes, gets a float argument passed as a double, and converts it to a float since the argument was declared to be float. (A subtle point here, evidently applicable in your case, is that it is sometimes possible to convert a double to a float by simply ignoring its low-order half. Sounds like you're running on a VAX, where this works. Most modern machines use IEEE floating point, in which the trick doesn't work because double has more exponent bits as well as more mantissa bits, so the high-order half of a double isn't laid out the same way as a float.) K&R1 C silently rewrote float to double, but didn't rewrite char to int. (Mostly because the ignore-lower-order trick is pretty dependable for int->char but not for double->float.) ANSI C rewrites neither. This point is actually discussed in the Rationale section for 3.7.1. -- "Maybe we should tell the truth?" | Henry Spencer at U of Toronto Zoology "Surely we aren't that desperate yet." | henry@zoo.toronto.edu utzoo!henry