www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Is this a bug in return type inference?

reply "Meta" <jared771 gmail.com> writes:
import std.random;

auto test(int n)
{
     if (n >= 0 && n < 33)
     {
         return int(0);
     }
     else if (n >= 33 && n < 66)
     {
         return float(0);
     }
     else
     {
         return real(0);
     }
}

void main()
{
     auto n = uniform(0, 100);
     auto res = test(n);
     //Prints "float"
     pragma(msg, typeof(res));
}

I expected the result to be real. Why is the return type of test 
inferred as float instead? I would expect it to choose real, as 
both int and float can be converted to real without precision 
loss, but the opposite is not true. Is this a bug?
Apr 26 2015
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 04/26/2015 12:32 PM, Meta wrote:
 import std.random;

 auto test(int n)
 {
      if (n >= 0 && n < 33)
      {
          return int(0);
      }
      else if (n >= 33 && n < 66)
      {
          return float(0);
      }
      else
      {
          return real(0);
      }
 }

 void main()
 {
      auto n = uniform(0, 100);
      auto res = test(n);
      //Prints "float"
      pragma(msg, typeof(res));
 }

 I expected the result to be real. Why is the return type of test
 inferred as float instead? I would expect it to choose real, as both int
 and float can be converted to real without precision loss, but the
 opposite is not true. Is this a bug?
Yes, a bug for floating types only. It seems that not the common type but the first type is used among floating point types. I wrote a short program to prove it to myself: import std.traits; import std.typetuple; import std.format; auto foo(A, B)(int n) { if (n) { return A(0); } else { return B(0); } } void main() { alias types = TypeTuple!(float, double, real); foreach (A; types) { foreach (B; types) { alias ReturnType = typeof(foo!(A, B)(0)); pragma(msg, format("%s %s -> %s%s", A.stringof, B.stringof, ReturnType.stringof, (is (ReturnType == CommonType!(A, B)) ? "" : " <-- BUG"))); } } } float float -> float float double -> float <-- BUG float real -> float <-- BUG double float -> double double double -> double double real -> double <-- BUG real float -> real real double -> real real real -> real Ali
Apr 26 2015
parent "Meta" <jared771 gmail.com> writes:
On Sunday, 26 April 2015 at 20:21:32 UTC, Ali Çehreli wrote:
 Yes, a bug for floating types only. It seems that not the 
 common type but the first type is used among floating point 
 types. I wrote a short program to prove it to myself:

 import std.traits;
 import std.typetuple;
 import std.format;

 auto foo(A, B)(int n)
 {
     if (n) {
         return A(0);

     } else {

         return B(0);
     }
 }

 void main()
 {
     alias types = TypeTuple!(float, double, real);

     foreach (A; types) {
         foreach (B; types) {
             alias ReturnType = typeof(foo!(A, B)(0));

             pragma(msg, format("%s %s -> %s%s",
                                A.stringof, B.stringof,
                                ReturnType.stringof,
                                (is (ReturnType == 
 CommonType!(A, B))
                                 ? ""
                                 : " <-- BUG")));
         }
     }
 }

 float float -> float
 float double -> float <-- BUG
 float real -> float <-- BUG
 double float -> double
 double double -> double
 double real -> double <-- BUG
 real float -> real
 real double -> real
 real real -> real

 Ali
https://issues.dlang.org/show_bug.cgi?id=14506
Apr 26 2015