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
Top | Discussion index | About this forum | D home