Jump to page: 1 2 3
Thread overview
auto limitation?
Sep 11, 2012
Namespace
Sep 11, 2012
Ali Çehreli
Sep 11, 2012
Namespace
Sep 11, 2012
Ali Çehreli
Sep 11, 2012
Namespace
Sep 11, 2012
Simen Kjaeraas
Sep 11, 2012
Denis Shelomovskij
Sep 11, 2012
Maxim Fomin
Sep 11, 2012
Namespace
Sep 11, 2012
Maxim Fomin
Sep 11, 2012
Simen Kjaeraas
Sep 11, 2012
Maxim Fomin
Sep 11, 2012
Namespace
Sep 11, 2012
Timon Gehr
Sep 11, 2012
Namespace
Sep 11, 2012
Timon Gehr
Sep 11, 2012
Namespace
Sep 11, 2012
Namespace
Sep 11, 2012
Maxim Fomin
Sep 11, 2012
bearophile
Sep 11, 2012
Namespace
Sep 11, 2012
Jonathan M Davis
Sep 11, 2012
bearophile
Sep 11, 2012
Jonathan M Davis
Sep 11, 2012
Jonathan M Davis
Sep 11, 2012
Namespace
Sep 11, 2012
Jonathan M Davis
Sep 12, 2012
Graham Fawcett
Sep 12, 2012
Namespace
September 11, 2012
I have this code, but it works not as expected:
http://dpaste.dzfl.pl/6ce5b4dd

I get 0 instead of 42 if my type is Int.
My value is correct (as you can see) but "writeln" prints still 0 instead of 42.
I think "auto" compiles first to float and cannot handle then integers.
Am I right? And could you explain me how this could work?
September 11, 2012
On 09/11/2012 11:10 AM, Namespace wrote:
> I have this code, but it works not as expected:
> http://dpaste.dzfl.pl/6ce5b4dd
>
> I get 0 instead of 42 if my type is Int.
> My value is correct (as you can see) but "writeln" prints still 0
> instead of 42.
> I think "auto" compiles first to float and cannot handle then integers.
> Am I right? And could you explain me how this could work?

Here is a reduced code:

import std.stdio;

enum Type { Int, Float }

auto foo(Type t)
{
    final switch (t) {
    case Type.Int:
        return 42;
    case Type.Float:
        return 1.5;
    }
}

void main()
{
    writeln(foo(Type.Int));
    writeln(foo(Type.Float));
}

The return type of foo() is double. (It's float in your code but it doesn't matter.)

I think this is a bug. I guess that 'return 42' is still placing an int onto the program stack instead of a float. A workarounds are returning to!float(this._num.ivalue).

But I think this is a compiler bug.

Ali
September 11, 2012
> Here is a reduced code:
>
> import std.stdio;
>
> enum Type { Int, Float }
>
> auto foo(Type t)
> {
>     final switch (t) {
>     case Type.Int:
>         return 42;
>     case Type.Float:
>         return 1.5;
>     }
> }
>
> void main()
> {
>     writeln(foo(Type.Int));
>     writeln(foo(Type.Float));
> }
>
> The return type of foo() is double. (It's float in your code but it doesn't matter.)
>
> I think this is a bug. I guess that 'return 42' is still placing an int onto the program stack instead of a float. A workarounds are returning to!float(this._num.ivalue).
>
> But I think this is a compiler bug.
>
> Ali

I should begin to count the bugs I find with stuff like this. :)
So no correct workaround, hm?

I tried to use a Variant and in the getter method "get" and even "coerce" but then i get the error, that the type of "get" cannot be detected.
September 11, 2012
On 09/11/2012 11:40 AM, Namespace wrote:
>> Here is a reduced code:
>>
>> import std.stdio;
>>
>> enum Type { Int, Float }
>>
>> auto foo(Type t)
>> {
>> final switch (t) {
>> case Type.Int:
>> return 42;
>> case Type.Float:
>> return 1.5;
>> }
>> }
>>
>> void main()
>> {
>> writeln(foo(Type.Int));
>> writeln(foo(Type.Float));
>> }
>>
>> The return type of foo() is double. (It's float in your code but it
>> doesn't matter.)
>>
>> I think this is a bug. I guess that 'return 42' is still placing an
>> int onto the program stack instead of a float. A workarounds are
>> returning to!float(this._num.ivalue).
>>
>> But I think this is a compiler bug.
>>
>> Ali
>
> I should begin to count the bugs I find with stuff like this. :)

Please create a bug about this one:

  http://d.puremagic.com/issues/

But wait until someone else confirms that it really is a bug. :)

> So no correct workaround, hm?

You have to cast the types to the largest one. The following does not work because foo() is not defined yet:

import std.traits;
// ...
auto foo(Type t)
{
    final switch (t) {
    case Type.Int:
        return to!(ReturnType!(typeof(&foo)))(42);
    case Type.Float:
        return 1.5;
    }
}

  Error: forward reference to foo

Explicitly casting is a way:

        return to!double(42);

Or you can write or find a template that produces the largest type among the members of a union.

Ali

September 11, 2012
That's not what i want. I would avoid casting if it's possible.
I hope it is a bug and will fixed in 2.061.
September 11, 2012
On Tuesday, 11 September 2012 at 18:32:47 UTC, Ali Çehreli wrote:
>
> Here is a reduced code:
>

I guess it may be reduced to:

auto foo(bool val)
{
   if (val)
      return 42;
   else
      return 1.5;
}

void main()
{
   assert(foo(true) == 42); // assertion failure
   assert(foo(false) == 1.5);
}


>
> The return type of foo() is double. (It's float in your code but it doesn't matter.)
>
> I think this is a bug. I guess that 'return 42' is still placing an int onto the program stack instead of a float. A workarounds are returning to!float(this._num.ivalue).
>
> But I think this is a compiler bug.
>
> Ali

I think it is UB rather than a bug. The spec says that return types must match exactly. AFAIK auto is a feature to infer return type, not to magically adjust to multiple incompatible types.

September 11, 2012
> I think it is UB rather than a bug. The spec says that return types must match exactly. AFAIK auto is a feature to infer return type, not to magically adjust to multiple incompatible types.

But i thought Variant is one. ;)
September 11, 2012
On Tue, 11 Sep 2012 20:48:25 +0200, Ali Çehreli <acehreli@yahoo.com> wrote:

> Or you can write or find a template that produces the largest type among the members of a union.

std.traits.CommonType.

-- 
Simen
September 11, 2012
On Tue, 11 Sep 2012 20:57:07 +0200, Maxim Fomin <maxim@maxim-fomin.ru> wrote:

> I think it is UB rather than a bug. The spec says that return types must match exactly. AFAIK auto is a feature to infer return type, not to magically adjust to multiple incompatible types.

I'd be surprised if this were not a bug. My expectation would be that the
types be combined as with the ?: operator, just like std.traits.CommonType.

If this is not a bug, it's certainly worth filing as an enhancement request.

-- 
Simen
September 11, 2012
On Tuesday, 11 September 2012 at 19:03:56 UTC, Namespace wrote:
>> I think it is UB rather than a bug. The spec says that return types must match exactly. AFAIK auto is a feature to infer return type, not to magically adjust to multiple incompatible types.
>
> But i thought Variant is one. ;)

I guess (never used Variant) that it uses templated getter which correctly returns value. Float values are returned in %xmm registers and integer values are returned in %eax. Without knowing return type a caller doesn't know where to take return value. For example in this case foo function correctly places return values, but main takes in both cases return value from %xmm.


« First   ‹ Prev
1 2 3