www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 11070] New: Allow auto statement in a switch statement

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

           Summary: Allow auto statement in a switch statement
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: DMD
        AssignedTo: nobody puremagic.com
        ReportedBy: andrej.mitrovich gmail.com



10:40:13 PDT ---
Currently if you want to handle an unhandled case in a switch statement you can
use a default statement. For example:

-----
import std.string;

auto get() { return "c"; }

void main()
{
    auto res = get();
    switch (res)
    {
        case "a": break;
        case "b": break;
        default:  assert(0, format("Unhandled case: '%s'", res));
    }

    /// res still visible here, we don't want it to be.
}
-----

The problem here is that you're unnecessarily creating the 'res' variable which
you will only use for the default statement. Additionally, such a variable
shouldn't be visible outside the switch statement if it's only going to be used
inside of the switch statement.

I propose we allow an auto statement in the switch statement:

-----
import std.string;

auto get() { return "c"; }

void main()
{
    switch (auto res = get())  // new: allow auto statement
    {
        case "a": break;
        case "b": break;
        default:  assert(0, format("Unhandled case: '%s'", res));
    }
}
-----

This will also eliminate the need for code duplication in switch statements
which use a common label statement, for example:

-----
import std.string;
import std.stdio;

auto get() { return "d"; }

void main()
{
    switch (auto res = get())
    {
        case "a": goto common;
        case "b": goto common;
        case "c": goto common;

        common:
            writefln("Got result: %s", res);
            break;

        default:  assert(0, format("Unhandled case: '%s'", res));
    }
}
-----

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


bearophile_hugs eml.cc changed:

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




 Additionally, such a variable
 shouldn't be visible outside the switch statement if it's only going to be used
 inside of the switch statement.
That's easy solved: auto get() { return "c"; } void main() { import std.string; { auto res = get; switch (res) { case "a": break; case "b": break; default: assert(0, format("Unhandled case: '%s'", res)); } } // res not visible here. }
 This will also eliminate the need for code duplication in switch statements
 which use a common label statement, for example:
 
 -----
 import std.string;
 import std.stdio;
 
 auto get() { return "d"; }
 
 void main()
 {
     switch (auto res = get())
     {
         case "a": goto common;
         case "b": goto common;
         case "c": goto common;
 
         common:
             writefln("Got result: %s", res);
             break;
 
         default:  assert(0, format("Unhandled case: '%s'", res));
     }
 }
Usually common bodies for case statements are not a big problem in D: auto get() { return "d"; } void main() { import std.stdio, std.string; { auto res = get; switch (res) { case "a", "b", "c": writefln("Got result: %s", res); break; default: assert(0, format("Unhandled case: '%s'", res)); } } // res not visible here. } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 19 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11070




13:22:09 PDT ---

 That's easy solved.
That's really ugly. It also gets twice as ugly if you have to use a static if.
 Usually common bodies for case statements are not a big problem in D.
Sometimes you have to call specific code for each of these cases, but then follow them with a generic call. So you use a goto to a single label. At the point of the label you won't know what the switch value is unless you stored it somewhere, e.g. (pseudocode): void main() { switch (auto x = get) { case "a": handleA(); goto common; case "b": handleB(); goto common; case "c": handleC(); goto common; common: log_output(x); break; default: } } -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 19 2013
prev sibling next sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11070


monarchdodra gmail.com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |monarchdodra gmail.com



Well, not just auto, you just want to be able to make a declaration inside the
switch expression. This would also apply to a while statement too.

In C++, this is legal:

//----
    while (int i = 1)
    {}

    switch (int i = 1)
    {}
//----

This is a very reduced use case, but I've seen cases where it is useful.

The D grammar does not allow it though. I don't see why not though.

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


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

           What    |Removed                     |Added
----------------------------------------------------------------------------
            Summary|Allow auto statement in a   |Allow declaration statement
                   |switch statement            |in a switch expression



15:10:21 PDT ---

 Well, not just auto, you just want to be able to make a declaration inside the
 switch expression.
Yeah, I'll rename the title. -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 19 2013
prev sibling parent d-bugmail puremagic.com writes:
http://d.puremagic.com/issues/show_bug.cgi?id=11070





 Well, not just auto, you just want to be able to make a declaration inside the
 switch expression. This would also apply to a while statement too.
 
 In C++, this is legal:
 
 //----
     while (int i = 1)
     {}
 
     switch (int i = 1)
     {}
 //----
 
 This is a very reduced use case, but I've seen cases where it is useful.
 
 The D grammar does not allow it though. I don't see why not though.
To answer my own self:
     while (int i = 1)
     {}
This would probably be illegal in D anyways, since we aren't allowed assignments in if/for/while. Arguably, it's not an "assignment" but a "declaration", so it shouldn't be a problem either. Still, it's a thin line, and I have (albeit very rarely) also made that "typo", when copy pasting code.
     switch (int i = 1)
     {}
Switch is special, because it doesn't actually test the args, so I see better chances of this being made legal. IMO, while the use cases arn't very important, not supporting this for switch would just be a gratuitous deviation from C++ (IMO). Then again, C doesn't support it either (afaik), so... -- Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Sep 20 2013