www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 1878] New: foreach does not handle integral types appropriately

reply d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1878

           Summary: foreach does not handle integral types appropriately
           Product: D
           Version: unspecified
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: bugzilla digitalmars.com
        ReportedBy: andrei metalanguage.com


ubyte limit = whatever();
ubyte x;
foreach (e; 0 .. limit)
   x = e;

does not compile with warnings enabled. The compiler should recognize that a
compile-time constant (in this case 0) is passed in and choose the tightest
type (in this case ubyte) for iteration.


-- 
Feb 28 2008
next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1878


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com


--- Comment #1 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2012-10-28
16:06:36 PDT ---
I think a language change might end up breaking code which assumes the index
variable is always size_t.

The simplest workaround is to type the index variable:
    foreach (ubyte e; 0 .. limit)
        writeln(e);

Otherwise if we want type inference we could implement a library function:

import std.stdio;

struct Walk(T)
{
    T idx;
    T max;

     property T front() { return idx; }
     property void popFront() { ++idx; }
     property bool empty() { return !(idx < max); }
}

auto walk(L, U)(L lwr, U upr)
{
    assert(lwr <= U.max);
    return Walk!U(cast(U)lwr, upr);
}

void main()
{
    ubyte limit = 10;
    ubyte x;

    foreach (e; walk(0, limit))
    {
        writefln("%s %s", typeid(e), e);  // type is ubyte
    }
}

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 28 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1878


bearophile_hugs eml.cc changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |bearophile_hugs eml.cc


--- Comment #2 from bearophile_hugs eml.cc 2012-10-28 16:32:52 PDT ---
A wider benchmark:


import std.typetuple: TypeTuple;
import std.range: iota;
void main() {
    foreach (T; TypeTuple!(byte, ubyte, short, ushort,
                           int, uint, long, ulong))
        foreach (i; 0 .. cast(T)10)
            pragma(msg, T, "  ", typeof(i));
    pragma(msg, "");
    foreach (T; TypeTuple!(byte, ubyte, short, ushort,
                           int, uint, long, ulong))
        foreach (i; iota(0, cast(T)10))
            pragma(msg, T, "  ", typeof(i));
}


byte  int
ubyte  int
short  int
ushort  int
int  int
uint  uint
long  long
ulong  ulong

byte  int
ubyte  int
short  int
ushort  int
int  int
uint  uint
long  long
ulong  ulong

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Oct 28 2012
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1878


Lionello Lunesu <lio+bugzilla lunesu.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |lio+bugzilla lunesu.com


--- Comment #3 from Lionello Lunesu <lio+bugzilla lunesu.com> 2013-09-08
01:42:44 PDT ---
This bug is also the source of many false positives when bug 259 gets fixed. 

The problem is that ForeachRangeStatement is using typeCombine, which does the
C style integer promotion. It should probably use the ?: combine logic instead.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 08 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1878



--- Comment #4 from Lionello Lunesu <lio+bugzilla lunesu.com> 2013-09-08
02:14:15 PDT ---
I checked the difference between CondExp (?:) and ForeachRangeStatement. The
former only has a special case when the types of the two expressions are equal.
It would fix foreach(i;ubyte..ubyte) and similar, but would not address the
issue raised by the OP.

It's still worth merging the logic of CondExp with ForeachRangeStatement,
though, if only for predictability. In fact, a?0:ubyte should similarly not
evaluate to 'int' but to 'ubyte', for the exact same reasons.

https://github.com/D-Programming-Language/dmd/pull/2538

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 08 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=1878



--- Comment #5 from github-bugzilla puremagic.com 2013-09-12 22:03:13 PDT ---
Commit pushed to master at https://github.com/D-Programming-Language/dmd

https://github.com/D-Programming-Language/dmd/commit/565caec167fa303cb2320a2c6d8f957f06d07008
Merge pull request #2538 from lionello/bug1878

foreach range uses same logic as ?: for type deduction

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Sep 12 2013