Thread overview
switch ( Expression ) ScopeStatement
Jul 07, 2009
Derek Parnell
Jul 07, 2009
bearophile
Jul 07, 2009
Derek Parnell
Jul 07, 2009
Tim Matthews
Jul 07, 2009
Derek Parnell
Jul 07, 2009
Tim Matthews
Jul 07, 2009
Tim Matthews
Jul 07, 2009
Tim Matthews
Jul 07, 2009
BCS
July 07, 2009
I see that the syntax for 'switch' is ...

   switch ( Expression ) ScopeStatement

and ScopeStatement is either a BlockStatement or a NonEmptyStatement.

Meaning that

  switch (i) j = k;

is valid syntax! Why is that?

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell
July 07, 2009
On Mon, Jul 6, 2009 at 8:18 PM, Derek Parnell<derek@psych.ward> wrote:
> I see that the syntax for 'switch' is ...
>
>   switch ( Expression ) ScopeStatement
>
> and ScopeStatement is either a BlockStatement or a NonEmptyStatement.
>
> Meaning that
>
>  switch (i) j = k;
>
> is valid syntax! Why is that?

So you can write this, of course!

switch(x) case 1: break;

I mean, you sometimes need a one-case switch, yes?  ;)
July 07, 2009
Derek Parnell:
> is valid syntax! Why is that?

To allow train-wrecks like this one:

version(Tango) import tango.stdc.stdio;
void main(char[][] args) {
  if (args.length > 1)
    switch (args[1]) {
      int x = 1; // This initialization to 1 doesn't happen,
                 // it's the same as int x = void;
      case "1": printf("1! x=%d\n", x); break;
      case "2": printf("2! x=%d\n", x); break;
    }
}

Bye,
bearophile
July 07, 2009
On Mon, 06 Jul 2009 22:10:20 -0400, bearophile wrote:

> Derek Parnell:
>> is valid syntax! Why is that?
> 
> To allow train-wrecks like this one:
> 
> version(Tango) import tango.stdc.stdio;
> void main(char[][] args) {
>   if (args.length > 1)
>     switch (args[1]) {
>       int x = 1; // This initialization to 1 doesn't happen,
>                  // it's the same as int x = void;
>       case "1": printf("1! x=%d\n", x); break;
>       case "2": printf("2! x=%d\n", x); break;
>     }
> }

No quite the same thing, actually. You have highlighted another quirk with switch though.

My question was really about why is it that the first token after the "( Expression )" did not have to be a left-brace, but could be any statement at all.

  switch(x) funcA();
  switch(x) switch (y) {};

Just seems wrong somehow but I'm positive that the experts have a perfectly rational answer. I just hope I can understand it.

-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell
July 07, 2009
bearophile wrote:
> Derek Parnell:
>> is valid syntax! Why is that?
> 
> To allow train-wrecks like this one:
> 
> version(Tango) import tango.stdc.stdio;
> void main(char[][] args) {
>   if (args.length > 1)
>     switch (args[1]) {
>       int x = 1; // This initialization to 1 doesn't happen,
>                  // it's the same as int x = void;
>       case "1": printf("1! x=%d\n", x); break;
>       case "2": printf("2! x=%d\n", x); break;
>     }
> }
> 
> Bye,
> bearophile


You are looking at something completely different but is not limited to switches. Switchs are a bit like gotos and gotos can achieve this same skip initialization errors.
July 07, 2009
Hello bearophile,

> Derek Parnell:
> 
>> is valid syntax! Why is that?
>> 
> To allow train-wrecks like this one:
> 
> version(Tango) import tango.stdc.stdio;
> void main(char[][] args) {
> if (args.length > 1)
> switch (args[1]) {
> int x = 1; // This initialization to 1 doesn't happen,
> // it's the same as int x = void;
> case "1": printf("1! x=%d\n", x); break;
> case "2": printf("2! x=%d\n", x); break;
> }
> }
> Bye,
> bearophile

you want a train wreck?


void main()
{
   switch(5) default: { case 6: {} }
}


July 07, 2009
Derek Parnell wrote:
> On Mon, 06 Jul 2009 22:10:20 -0400, bearophile wrote:
> 
>> Derek Parnell:
>>> is valid syntax! Why is that?
>> To allow train-wrecks like this one:
>>
>> version(Tango) import tango.stdc.stdio;
>> void main(char[][] args) {
>>   if (args.length > 1)
>>     switch (args[1]) {
>>       int x = 1; // This initialization to 1 doesn't happen,
>>                  // it's the same as int x = void;
>>       case "1": printf("1! x=%d\n", x); break;
>>       case "2": printf("2! x=%d\n", x); break;
>>     }
>> }
> 
> No quite the same thing, actually. You have highlighted another quirk with
> switch though. 
> 
> My question was really about why is it that the first token after the "(
> Expression )" did not have to be a left-brace, but could be any statement
> at all. 
> 
>   switch(x) funcA();
>   switch(x) switch (y) {};
> 
> Just seems wrong somehow but I'm positive that the experts have a perfectly
> rational answer. I just hope I can understand it.
> 

Switch is really a neat form of comparison and gotos but with actual labels replaced with a case statement. A block statement is usually used to have more than one case statement valid. This is valid code but uncomment the next line and it becomes invalid:

module test;

import tango.io.Stdout;

void main(char[][] args)
{
  if (args.length > 1)
    switch (args[1])
      case "1": Stdout("1"); break;
      //case "2": Stdout("2"); break; //uncomment and error

}
July 07, 2009
On Tue, 07 Jul 2009 14:57:39 +1200, Tim Matthews wrote:

> Switch is really a neat form of comparison and gotos but with actual labels replaced with a case statement. A block statement is usually used to have more than one case statement valid. This is valid code but uncomment the next line and it becomes invalid:
> 
> module test;
> 
> import tango.io.Stdout;
> 
> void main(char[][] args)
> {
>    if (args.length > 1)
>      switch (args[1])
>        case "1": Stdout("1"); break;
>        //case "2": Stdout("2"); break; //uncomment and error
> 
> }

Actually that is not valid code. The first "break;" breaks the program.

This is valid ...

 module test;

 import tango.io.Stdout;

 void main(char[][] args)
 {
    if (args.length > 1)
      switch (args[1])
        case "1": Stdout("1"); // break; //uncomment and error
 }

Ok, why on earth would a one-case switch be useful? And that still doesn't help me understand why allowing other statement types in that position is a good idea.


-- 
Derek Parnell
Melbourne, Australia
skype: derek.j.parnell
July 07, 2009
Derek Parnell wrote:
> On Tue, 07 Jul 2009 14:57:39 +1200, Tim Matthews wrote:
> 
>> Switch is really a neat form of comparison and gotos but with actual labels replaced with a case statement. A block statement is usually used to have more than one case statement valid. This is valid code but uncomment the next line and it becomes invalid:
>>
>> module test;
>>
>> import tango.io.Stdout;
>>
>> void main(char[][] args)
>> {
>>    if (args.length > 1)
>>      switch (args[1])
>>        case "1": Stdout("1"); break;
>>        //case "2": Stdout("2"); break; //uncomment and error
>>
>> }
> 
> Actually that is not valid code. The first "break;" breaks the program.

yeah I forgot to remove the break as it was no longer part of the switch statement.


> Ok, why on earth would a one-case switch be useful? And that still doesn't
> help me understand why allowing other statement types in that position is a
> good idea.
> 
> 

C compatibility. It's not really a problem to D. If there is a compiler that only accepted block statements for switch not many people would care that it doesn't conform to C spec because no one uses it like that anyway.
July 07, 2009
Derek Parnell wrote:
> On Tue, 07 Jul 2009 14:57:39 +1200, Tim Matthews wrote:
> 
>> Switch is really a neat form of comparison and gotos but with actual labels replaced with a case statement. A block statement is usually used to have more than one case statement valid. This is valid code but uncomment the next line and it becomes invalid:
>>
>> module test;
>>
>> import tango.io.Stdout;
>>
>> void main(char[][] args)
>> {
>>    if (args.length > 1)
>>      switch (args[1])
>>        case "1": Stdout("1"); break;
>>        //case "2": Stdout("2"); break; //uncomment and error
>>
>> }
> 
> Actually that is not valid code. The first "break;" breaks the program.
> 

It shouldn't have accepted it so it's here now. http://d.puremagic.com/issues/show_bug.cgi?id=3144