View mode: basic / threaded / horizontal-split · Log in · Help
November 15, 2009
About switch case statements...
So, switch-case statements are a frequent source of nasty bugs.  Fixing
them (well) requires breaking backwards compatibility.

Any chance this will happen for D2?

(This is intended as more of a reminder and simple curiosity than a
discussion.)
November 15, 2009
Re: About switch case statements...
Chad J wrote:
> So, switch-case statements are a frequent source of nasty bugs.  Fixing
> them (well) requires breaking backwards compatibility.
> 
> Any chance this will happen for D2?
> 
> (This is intended as more of a reminder and simple curiosity than a
> discussion.)

I wish very much that a transferring control flow statement (break, 
return, goto etc.) is required at the end of each case. Then, the rare 
case when you want to break through is easy to implement as goto case 
xxx; and all is good.

Walter's answer to that has put me to silence for good. "But I use 
fall-through all the time!" I then knew the feature will never make it.


Andrei
November 15, 2009
Re: About switch case statements...
Chad J wrote:
> So, switch-case statements are a frequent source of nasty bugs.  Fixing
> them (well) requires breaking backwards compatibility.
> 
> Any chance this will happen for D2?
> 
> (This is intended as more of a reminder and simple curiosity than a
> discussion.)

The correct way to solve this is to create a new switch-case statement 
that doesn't suck. It would use a different syntax, and support spiffy 
stuff like pattern matching. If you wanted to use duff's device or need 
C compatibility, you still could use the old switch-case.
November 15, 2009
Re: About switch case statements...
On 2009-11-15 12:54:02 -0500, Andrei Alexandrescu 
<SeeWebsiteForEmail@erdani.org> said:

> Walter's answer to that has put me to silence for good. "But I use 
> fall-through all the time!" I then knew the feature will never make it.

Hum two suggestions. Sometime I want fall-through when I write a 
switch, but I always make it clear that it isn't a bug by writing the 
intent in a short comment:

	switch (c) {
		case 1:
			blah();
			break;
		case 2:
			blah();
			// fallthrough
		case 3:
			blah();
			break;
	}

That way I can always tell when I read again the code wether this was 
intentional or not. It wouldn't hurt at all if that "fallthrough" 
comment became a keyword:

	switch (c) {
		case 1:
			blah();
			break;
		case 2:
			blah();
			fallthrough;
		case 3:
			blah();
			break;
	}

Now the intent is clear even for the compiler.

-- 
Michel Fortin
michel.fortin@michelf.com
http://michelf.com/
November 15, 2009
Re: About switch case statements...
Andrei Alexandrescu wrote:
> 
> Walter's answer to that has put me to silence for good. "But I use
> fall-through all the time!" I then knew the feature will never make it.
> 

T_T

There has to be a better way to do fall-through.

Maybe...

switch(foo)
{
   case 0;
   case 1; bar = baz; // Executed if foo == 0
   case 2:
       doSomething(bar); // Executed for foo ∈ {0,1,2}
       break; //required for compile success.
}
November 15, 2009
Re: About switch case statements...
Chad J wrote:
> 
> There has to be a better way to do fall-through.
> 
> Maybe...
> 
> switch(foo)
> {
>     case 0;
>     case 1; bar = baz; // Executed if foo == 0
>     case 2:
>         doSomething(bar); // Executed for foo ∈ {0,1,2}
>         break; //required for compile success.
> }

or if you want it to look nicer, maybe introduce an arrow token:

switch(foo)
{
   case 0 ->
   case 1 -> bar = baz; // Executed if foo == 0
   case 2:
       doSomething(bar); // Executed for foo ∈ {0,1,2}
       break; //required for compile success.
}

It has these advantages:
* Fall-through behavior is explicit.
* Fall-through notation requires no extra lines of source, and only a
couple extra columns.

Sigh, I didn't want to discuss syntax, but that response... it makes me
want to solve problems, to say the least.
November 15, 2009
Re: About switch case statements...
Andrei Alexandrescu wrote:
> Chad J wrote:
>> So, switch-case statements are a frequent source of nasty bugs.  Fixing
>> them (well) requires breaking backwards compatibility.
>>
>> Any chance this will happen for D2?
>>
>> (This is intended as more of a reminder and simple curiosity than a
>> discussion.)
> 
> I wish very much that a transferring control flow statement (break, 
> return, goto etc.) is required at the end of each case. Then, the rare 
> case when you want to break through is easy to implement as goto case 
> xxx; and all is good.
> 
> Walter's answer to that has put me to silence for good. "But I use 
> fall-through all the time!" I then knew the feature will never make it.
> 
> 
> Andrei

For what its worth, in a (very domain specific) scripting language I've been working on, I 
used 'continue' to implement fall-through, and haven't felt too bad about it.  That and 
being able to do (case A, B, C:) helps for the most common (IME) sort of use.

//////////////////////////////////////////////////
.__receive system ( cmd: STR, @params )
    switch ( cmd .lowercase .tosym )
        case 'lo', 'login':
            user.tell( "(LOgin has been deprecated; please start using COnnect instead.)")
            continue;

        case 'co', 'connect':
            uname, pwd <- params;
            who = #Database::User.lookup( uname )
            if ( who.valid && who.accept_password( pwd ) )
		return .accept( user, who );
            end

        // ... and so on ...
    end
end
//////////////////////////////////////////////////

-- Chris Nicholson-Sauls
November 15, 2009
Re: About switch case statements...
Michel Fortin wrote:
> Hum two suggestions. Sometime I want fall-through when I write a switch, 
> but I always make it clear that it isn't a bug by writing the intent in 
> a short comment:
> 
>     switch (c) {
>         case 1:
>             blah();
>             break;
>         case 2:
>             blah();
>             // fallthrough
>         case 3:
>             blah();
>             break;
>     }

I just use whitespace:

     switch (c) {
         case 1:
             blah();
             break;

         case 2:
             blah();
         case 3:
             blah();
             break;
     }

Works fine.
November 15, 2009
Re: About switch case statements...
Chris Nicholson-Sauls wrote:
> For what its worth, in a (very domain specific) scripting language I've 
> been working on, I used 'continue' to implement fall-through, and 
> haven't felt too bad about it.

Using "continue" for that purpose would silently break a lot of existing 
code.
November 15, 2009
Re: About switch case statements...
Andrei Alexandrescu wrote:
> Chad J wrote:
>> So, switch-case statements are a frequent source of nasty bugs.  Fixing
>> them (well) requires breaking backwards compatibility.
>>
>> Any chance this will happen for D2?
>>
>> (This is intended as more of a reminder and simple curiosity than a
>> discussion.)
> 
> I wish very much that a transferring control flow statement (break, 
> return, goto etc.) is required at the end of each case. Then, the rare 
> case when you want to break through is easy to implement as goto case 
> xxx; and all is good.
> 
> Walter's answer to that has put me to silence for good. "But I use 
> fall-through all the time!" I then knew the feature will never make it.

Walter definitely *thinks* he uses fall-through all of the time. BUT...
Does he *really* use it all the time? It's not a matter of opinion; it's 
an objective question, answerable since so much of his code is now 
publically available. I got a bit interested in knowing how much he does 
use it.

I consider that fallthrough requires a non-empty statement. IE,
case A:
case B:
case C:
     dosomething();
     break;

is not a real fallthrough; those would always be allowed.

I looked through a couple of DMD files: parse.c, (the parser), and 
cod3.c (the largest file in the back-end).
In cod3, there are 381 case statements. There are 3 occasions where 
fallthrough is used. In two of those cases, they fallthrough to a label 
where other cases have 'goto' that label. In the remaining case, the 
code which was fallen through was an assert and a debug print statement.

parse.c has 541 case statements, I didn't find any fallthroughs in the 
first half of the code, but I didn't look as thoroughly as I did in cod3.

Based on this, it looks to me as though Walter uses fall-through very, 
very rarely. Less than 1% of all case statements.
For comparison, those files contain 178 and 137 gotos, respectively <g>.
Walter does use 'goto'. He doesn't use fallthrough in switch statements.

It's actually not something I care about at all. But I think Walter's 
wrong about his coding style. And looking at how rarely it's actually 
used by someone who thinks he uses it a lot, convinces me that 
intentional use of fall-through is much less common than bugs introduced 
by leaving out a break statement.

An interesting result.
But I'd much rather change Walter's mind about opPow() or the 
meta.compiles(XXX) proposal.
« First   ‹ Prev
1 2 3 4 5
Top | Discussion index | About this forum | D home