D's SwitchStatement accepts statements with ridiculous semantics

Timon Gehr timon.gehr at gmx.ch
Fri Sep 29 10:32:02 UTC 2017


On 29.09.2017 11:12, Don Clugston wrote:
> Guess what this prints
> 
> ----
> import std.stdio;
> 
> void main()
> {
>    int i = 0;
> 
>    switch (i) for (i = 8; i < 10; ++i)
>    {
>      case 7:
>          writeln(i);
>          return;
> 
>      default: ;
>    }
> }
> ----
> 
> 
> Why does this even compile? It's because the grammar is:
> 
> SwitchStatement:
>      switch ( Expression ) ScopeStatement
> 
> 
> and ScopeStatement allows almost anything.
> I think the only sane grammar is
> 
> SwitchStatement:
>      switch ( Expression ) BlockStatement
> 
> Initially I thought ScopeStatement was accepted in order to enable 
> Duff's device, but it isn't necessary for that. It might have originally 
> accepted ScopeStatement to support
> 
> E e; switch( e ) with (E) { .... }
> 
> Or it may have just been an accident.

It is very likely that this part of the grammar was deliberately copied 
from C. It's also consistent with how all other control flow constructs 
are parsed.

> But regardless of the original motivation, it allows some truly dreadful 
> semantics.

I don't see what your proposed grammar change accomplishes:

switch(i){
     for(i=8;i<10;++i){
         case 7:
             writeln(i);
             return;
         default:{}
     }
}

I.e., you seem to have misidentified the culprit. Whether or not to the 
curly braces are required by the parser has nothing to do with switch 
semantics.

> Can we disallow this silliness please?
> 

Maybe this specific case can be disallowed during semantic (but I don't 
really see why it helps, it mostly just makes the language definition 
more complex).


More information about the Digitalmars-d mailing list