Thread overview
case statement allows for runtime values, a case of accepts-invalid?
Apr 19, 2011
Andrej Mitrovic
Apr 19, 2011
Jesse Phillips
Apr 19, 2011
Andrej Mitrovic
Re: case statement allows for runtime values,
Apr 19, 2011
Jesse Phillips
Apr 19, 2011
Andrej Mitrovic
Apr 19, 2011
Jesse Phillips
Apr 19, 2011
bearophile
Apr 19, 2011
Andrej Mitrovic
April 19, 2011
int foo(ref int y)
{
    y = 5;
    return y;
}

void main()
{
    int x = 1;
    int y = 2;

    switch (x = foo(y))
    {
        case y:
            writeln("x == y");
        default:
    }

    assert(x == 5);
    assert(y == 5);
}

According to the docs:
The case expressions must all evaluate to a constant value or array, or a runtime initialized const or immutable variable of integral type.

In fact if you try to add a constant, only then will you get an error:
    switch (x)
    {
        case y + 1:
    }
Error: case must be a string or an integral constant, not y + 1

It will also error out if you try to use a field of a struct. Which leads me to believe the first case should not be allowed to compile. Thoughts?

April 19, 2011
Andrej Mitrovic Wrote:

> int foo(ref int y)
> {
>     y = 5;
>     return y;
> }
> 
> void main()
> {
>     int x = 1;
>     int y = 2;
> 
>     switch (x = foo(y))
>     {
>         case y:
>             writeln("x == y");
>         default:
>     }
> 
>     assert(x == 5);
>     assert(y == 5);
> }

Yes bug. Not this part though

>     switch (x = foo(y))
April 19, 2011
On 4/19/11, Jesse Phillips <jessekphillips+D@gmail.com> wrote:
> Yes bug. Not this part though
>
>>     switch (x = foo(y))
>

Yeah that I know.

Do you happen to know if this bug is already filed or should I file it?
April 19, 2011
*I've searched bugzilla and couldn't find an entry for this particular case.
April 19, 2011
Andrej Mitrovic Wrote:

> On 4/19/11, Jesse Phillips <jessekphillips+D@gmail.com> wrote:
> > Yes bug. Not this part though
> >
> >>     switch (x = foo(y))
> >
> 
> Yeah that I know.
> 
> Do you happen to know if this bug is already filed or should I file it?

I would not know. As long as you do a best guess search on what you think it would be in Bugzilla, post the bug. It is best to have a duplicate here and there then to miss something. In fact even when something seems similar it is good to post a new bug when you're not sure (mention possibly related bugs in the report).
April 19, 2011
Got it. Bug is reported.

Btw, is there a specific reason why non-const values are not allowed?

I mean, doesn't a switch statement like this:
switch(value)
{
    case 1:
        foo(); break;
    case 2:
        bar(); break;
    default:
        doo();
}

expand to:

if (value == 1)
    foo();
else if (value == 2)
    bar();
else
    doo();

You can compare anything in an if statement, so why is switch more limited?
April 19, 2011
Andrej Mitrovic Wrote:

> Got it. Bug is reported.
> 
> Btw, is there a specific reason why non-const values are not allowed?
> 
> I mean, doesn't a switch statement like this:
> switch(value)
> {
>     case 1:
>         foo(); break;
>     case 2:
>         bar(); break;
>     default:
>         doo();
> }
> 
> expand to:
> 
> if (value == 1)
>     foo();
> else if (value == 2)
>     bar();
> else
>     doo();
> 
> You can compare anything in an if statement, so why is switch more limited?

No, it doesn't lower to an if/else statement. I didn't quite understand the details, but I'm actually pretty sure it needs a compile-time value.
April 19, 2011
Andrej Mitrovic:

> Got it. Bug is reported.

Good.


> You can compare anything in an if statement, so why is switch more limited?

switch has stronger requirements than a series of if statements and its uses such extra information to create assembly code that's more efficient than a series of if statement, like a dense jump table. (And in some situations there are ways to produce something even better, if you need to emulate a state machine or an interpreter. You are able to do it in GCC with computed gotos).

Bye,
bearophile