On Tue, 07 Jul 2009 21:05:45 -0400, Walter Bright <[email protected]> wrote:

Andrei Alexandrescu wrote:
Robert Jacques wrote:
long g;
g = e + f;  => d = cast(long) e + cast(long) f;

Works today.

Wrong. I just tested this and what happens today is:
g = cast(long)(e+f);
And this is (I think) correct behavior according to the new rules and not a bug. In the new rules int is special, in this suggestion, it's not.
I think this is a good idea that would improve things. I think, however, it would be troublesome to implement because expressions are typed bottom-up. The need here is to "teleport" type information from the assignment node to the addition node, which is downwards. And I'm not sure how this would generalize to other operators beyond "=".

It's also troublesome because it would silently produce different answers than C would.

Please, correct me if I'm wrong, but it seems C works by promoting byte/short/etc to int and then casting back down if need be. (Something tells me this wasn't always true) So (I think) the differences would be limited to integer expressions assigned to longs. Also, doing this 'right' might be important to 64-bit platforms.

Actually, after finding and skiming the C spec (from http://frama-c.cea.fr/download/acsl_1.4.pdf via wikipedia)

"
2.2.3 Typing
The language of logic expressions is typed (as in multi-sorted first-order logic). Types are either C types
or logic types defined as follows:
 ?mathematical? types: integer for unbounded, mathematical integers, real for real numbers,
boolean for booleans (with values written \true and \false);
 logic types introduced by the specification writer (see Section 2.6).
There are implicit coercions for numeric types:
 C integral types char, short, int and long, signed or unsigned, are all subtypes of type
integer;
 integer is itself a subtype of type real;
 C types float and double are subtypes of type real.

...

2.2.4 Integer arithmetic and machine integers
The following integer arithmetic operations apply to mathematical integers: addition, subtraction, multiplication, unary minus. The value of a C variable of an integral type is promoted to a mathematical integer. As a consequence, there is no such thing as "arithmetic overflow" in logic expressions. Division and modulo are also mathematical operations, which coincide with the corresponding C operations on C machine integers, thus following the ANSI C99 conventions. In particular, these are not the usual mathematical Euclidean division and remainder. Generally speaking, division rounds the result towards zero. The results are not specified if divisor is zero; otherwise if q and r are the quotient and the
remainder of n divided by d then:"
"

So by the spec   (and please correct me if I'm reading this wrong)
g = e + f => g = cast(long)(  cast(integer)e + cast(integer)f  );
where integer is unbounded in bits (and therefore has no overflow)
therefore
g = e + f;  => d = cast(long) e + cast(long) f;
is more in keeping with the spec than
g = cast(long)(e+f);
in terms of a practical implementation, since there's less possibility for overflow error.

(Caveat: most 32-bit compilers probably defaulted integer to int, though 64-bit compilers are probably defaulting integer to long.)






Reply via email to