dmd 1.046 and 2.031 releases
Robert Jacques
sandford at jhu.edu
Tue Jul 7 19:06:21 PDT 2009
On Tue, 07 Jul 2009 21:05:45 -0400, Walter Bright
<newshound1 at digitalmars.com> 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.)
More information about the Digitalmars-d-announce
mailing list