Thread overview | |||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 11, 2012 auto limitation? | ||||
---|---|---|---|---|
| ||||
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 Re: auto limitation? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | 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 Re: auto limitation? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | > 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 Re: auto limitation? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | 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 Re: auto limitation? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 Re: auto limitation? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 Re: auto limitation? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxim Fomin | > 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 Re: auto limitation? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | 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 Re: auto limitation? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Maxim Fomin | 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 Re: auto limitation? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Namespace | 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.
|
Copyright © 1999-2021 by the D Language Foundation