View mode: basic / threaded / horizontal-split · Log in · Help
April 19, 2011
case statement allows for runtime values, a case of accepts-invalid?
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
Re: case statement allows for runtime values, a case of accepts-invalid?
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
Re: case statement allows for runtime values, a case of accepts-invalid?
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
Re: case statement allows for runtime values, a case of accepts-invalid?
*I've searched bugzilla and couldn't find an entry for this particular case.
April 19, 2011
Re: case statement allows for runtime values,
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
Re: case statement allows for runtime values,
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
Re: case statement allows for runtime values,
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
Re: case statement allows for runtime values,
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