Thread overview
Clarification on testsuite 'runnable/testmath.d'
Jan 14, 2012
Daniel Green
Jan 14, 2012
Walter Bright
Jan 14, 2012
Daniel Green
Jan 14, 2012
Iain Buclaw
Jan 14, 2012
Daniel Green
Jan 14, 2012
Iain Buclaw
January 14, 2012
I've been working on fixing GDC/MinGW's runtime support.  I ran across the following and was hoping to get a clarification on what DMD does differently than GDC.

void testexp()
{
    printf("exp(3.0) = %Lg, %Lg\n", exp(3.0), E * E * E);
    assert(equals(exp(3.0), E * E * E, 16));
}

Of interest is exp(3.0).  GDC matches exp(3.0) to double exp(double). This causes problems with printf due to %Lg wanting a real but only receiving a double.

Looking at the D specification for overloading functions.
    1. no match
    2. match with implicit conversions
    3. match with conversion to const
    4. exact match


The specification doesn't indicate what levels are better.  I would guess 4 is the best since an exact match should take precedence.
However, that results in GDC matching exp(3.0) to double exp(double).

How does DMD match exp(3.0)?

Could it possibly be a typo?  For 32-bit this test passes because the printf doesn't segfault, it's only  noticeable with 64-bit since it segfaults.
January 14, 2012
On 1/13/2012 10:51 PM, Daniel Green wrote:
> Could it possibly be a typo? For 32-bit this test passes because the printf
> doesn't segfault, it's only noticeable with 64-bit since it segfaults.

3.0 should match double, when there is both double and real.
January 14, 2012
I think the only difference may be that gdc possibly folds the call to
exp().

Check the difference between what code gdc generates compared to how gcc processed it:  -fdump-tree-original  -fdump-tree-optimized

----
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';

On 14 Jan 2012 06:56, "Daniel Green" <venix1@gmail.com> wrote:
>
> I've been working on fixing GDC/MinGW's runtime support.  I ran across
the following and was hoping to get a clarification on what DMD does differently than GDC.
>
> void testexp()
> {
>    printf("exp(3.0) = %Lg, %Lg\n", exp(3.0), E * E * E);
>    assert(equals(exp(3.0), E * E * E, 16));
> }
>
> Of interest is exp(3.0).  GDC matches exp(3.0) to double exp(double).
This causes problems with printf due to %Lg wanting a real but only receiving a double.
>
> Looking at the D specification for overloading functions.
>    1. no match
>    2. match with implicit conversions
>    3. match with conversion to const
>    4. exact match
>
>
> The specification doesn't indicate what levels are better.  I would guess
4 is the best since an exact match should take precedence.
> However, that results in GDC matching exp(3.0) to double exp(double).
>
> How does DMD match exp(3.0)?
>
> Could it possibly be a typo?  For 32-bit this test passes because the
printf doesn't segfault, it's only  noticeable with 64-bit since it segfaults.


January 14, 2012
On 1/14/2012 3:29 AM, Walter Bright wrote:
> On 1/13/2012 10:51 PM, Daniel Green wrote:
>> Could it possibly be a typo? For 32-bit this test passes because the
>> printf
>> doesn't segfault, it's only noticeable with 64-bit since it segfaults.
>
> 3.0 should match double, when there is both double and real.

On 1/14/2012 3:29 AM, Walter Bright wrote:
> On 1/13/2012 10:51 PM, Daniel Green wrote:
>> Could it possibly be a typo? For 32-bit this test passes because the
>> printf
>> doesn't segfault, it's only noticeable with 64-bit since it segfaults.
>
> 3.0 should match double, when there is both double and real.

When I run the following through DMD r is type real.  For GDC r is type double.

The matched function would be
   double exp(double x) @safe pure nothrow  { return exp(cast(real)x); }.

Is it expected that DMD promotes a double to real?


// GDC: r is type double
// DMD: r is type real
import std.stdio;
import std.math;

void main()
{
    auto r = exp(3.0);
    writefln("%s", typeof(r).stringof);
}
January 14, 2012
On 14 January 2012 15:20, Daniel Green <venix1@gmail.com> wrote:
> On 1/14/2012 3:29 AM, Walter Bright wrote:
>>
>> On 1/13/2012 10:51 PM, Daniel Green wrote:
>>>
>>> Could it possibly be a typo? For 32-bit this test passes because the
>>> printf
>>> doesn't segfault, it's only noticeable with 64-bit since it segfaults.
>>
>>
>> 3.0 should match double, when there is both double and real.
>
>
> On 1/14/2012 3:29 AM, Walter Bright wrote:
>> On 1/13/2012 10:51 PM, Daniel Green wrote:
>>> Could it possibly be a typo? For 32-bit this test passes because the
>>> printf
>>> doesn't segfault, it's only noticeable with 64-bit since it segfaults.
>>
>> 3.0 should match double, when there is both double and real.
>
> When I run the following through DMD r is type real.  For GDC r is type double.
>
> The matched function would be
>   double exp(double x) @safe pure nothrow  { return exp(cast(real)x); }.
>
> Is it expected that DMD promotes a double to real?
>
>
> // GDC: r is type double
> // DMD: r is type real
> import std.stdio;
> import std.math;
>
> void main()
> {
>    auto r = exp(3.0);
>    writefln("%s", typeof(r).stringof);
> }

Strange, I get 'double' for both DMD and GDC... is this maybe a Windows thing?


-- 
Iain Buclaw

*(p < e ? p++ : p) = (c & 0x0f) + '0';
January 14, 2012
On 1/14/2012 10:34 AM, Iain Buclaw wrote:
> Strange, I get 'double' for both DMD and GDC... is this maybe a Windows thing?

Just ran it with linux and got 'double' as well.  So it appears to be a Windows thing.