Jump to page: 1 28  
Page
Thread overview
so what about switch()
Feb 12, 2002
Pavel Minayev
Feb 12, 2002
Sean L. Palmer
Feb 12, 2002
Walter
Feb 12, 2002
Pavel Minayev
Feb 12, 2002
Walter
Feb 12, 2002
Pavel Minayev
Feb 22, 2002
Jon Allen
Feb 22, 2002
Sean L. Palmer
Feb 23, 2002
Karl Bochert
Feb 23, 2002
Sean L. Palmer
Feb 12, 2002
Walter
Feb 12, 2002
D
Feb 12, 2002
Pavel Minayev
Feb 12, 2002
Sean L. Palmer
Feb 12, 2002
Richard Krehbiel
Feb 12, 2002
Walter
Feb 12, 2002
Sean L. Palmer
Feb 15, 2002
DrWhat?
Feb 15, 2002
Pavel Minayev
Feb 16, 2002
Sean L. Palmer
Feb 16, 2002
Pavel Minayev
Feb 16, 2002
Russ Lewis
Feb 16, 2002
Pavel Minayev
Feb 18, 2002
Roberto Mariottini
Feb 18, 2002
Pavel Minayev
Feb 18, 2002
OddesE
Feb 18, 2002
Russ Lewis
Feb 19, 2002
Sean L. Palmer
Feb 19, 2002
Pavel Minayev
Feb 20, 2002
Sean L. Palmer
Feb 20, 2002
OddesE
Feb 21, 2002
Karl Bochert
Feb 21, 2002
Russell Borogove
Feb 21, 2002
Pavel Minayev
Feb 21, 2002
Russell Borogove
Feb 21, 2002
Sean L. Palmer
Feb 21, 2002
Karl Bochert
Feb 21, 2002
Pavel Minayev
Feb 21, 2002
Karl Bochert
Feb 21, 2002
Pavel Minayev
Feb 22, 2002
OddesE
Feb 22, 2002
Pavel Minayev
Feb 22, 2002
Russell Borogove
Feb 22, 2002
Pavel Minayev
Feb 22, 2002
Russell Borogove
Feb 12, 2002
Russ Lewis
Feb 12, 2002
Russ Lewis
Feb 12, 2002
Pavel Minayev
Feb 12, 2002
Russ Lewis
Feb 12, 2002
Russ Lewis
Feb 12, 2002
Walter
Feb 12, 2002
Pavel Minayev
Feb 12, 2002
Russ Lewis
Power switch()
Feb 14, 2002
Juarez Rudsatz
Feb 15, 2002
DrWhat?
Feb 15, 2002
Pavel Minayev
Feb 15, 2002
DrWhat?
Feb 15, 2002
d
Feb 15, 2002
Walter
Feb 16, 2002
Sean L. Palmer
Feb 17, 2002
OddesE
Feb 17, 2002
Sean L. Palmer
Feb 18, 2002
OddesE
Feb 21, 2002
d
Feb 22, 2002
Sean L. Palmer
Feb 22, 2002
Pavel Minayev
Re: Power switch() "next"
Feb 22, 2002
Martin York
Feb 22, 2002
Pavel Minayev
Mar 04, 2002
d
Feb 22, 2002
Pavel Minayev
Mar 04, 2002
d
Feb 23, 2002
Walter
Mar 04, 2002
d
Feb 22, 2002
Richard Krehbiel
Feb 22, 2002
OddesE
Feb 22, 2002
Pavel Minayev
Feb 22, 2002
Russ Lewis
February 12, 2002
Yeah, once again back to the old topic... Walter, are you going
to provide some neater, more powerful, and less error-prone
alternative to this #&!% C switch()? It's one of the most frequent
sources of bugs, IMO, and the way it works is not intuitive
and absolutely anti-C(D), in general.

My suggestion of syntax:

    select (n)
    {
        case (0)
            foo();
        case (1, 3, 7)
        {
            int m = foo(n);
            bar(n);
        }
        case (2, 4 .. 6, 9)
            bar(n);
        default
            throw new Error;
    }

This should deal with most switch() problems:

    - no more break; only one case-block gets executed. Block statement
      is required if there are more then one statement in case (just
      like all other D constructs)
    - easy to check for several possible values and/or ranges

What do you think of this?


February 12, 2002
Once break is no longer *required* in a switch, we can actually use break to break out of an enclosing loop, something I've wished for many times in the past.

Sean

"Pavel Minayev" <evilone@omen.ru> wrote in message news:a4ap6u$teg$1@digitaldaemon.com...
> Yeah, once again back to the old topic... Walter, are you going
> to provide some neater, more powerful, and less error-prone
> alternative to this #&!% C switch()? It's one of the most frequent
> sources of bugs, IMO, and the way it works is not intuitive
> and absolutely anti-C(D), in general.
>
> My suggestion of syntax:
>
>     select (n)
>     {
>         case (0)
>             foo();
>         case (1, 3, 7)
>         {
>             int m = foo(n);
>             bar(n);
>         }
>         case (2, 4 .. 6, 9)
>             bar(n);
>         default
>             throw new Error;
>     }
>
> This should deal with most switch() problems:
>
>     - no more break; only one case-block gets executed. Block statement
>       is required if there are more then one statement in case (just
>       like all other D constructs)
>     - easy to check for several possible values and/or ranges
>
> What do you think of this?
>
>


February 12, 2002
The difficulty I have is I haven't had problems with switch in my own code. I do like the idea of having multiple case values, though. The case range is a good idea, too. I don't want to change the fall through behavior, though. Is it really such a problem?

"Pavel Minayev" <evilone@omen.ru> wrote in message news:a4ap6u$teg$1@digitaldaemon.com...
> Yeah, once again back to the old topic... Walter, are you going
> to provide some neater, more powerful, and less error-prone
> alternative to this #&!% C switch()? It's one of the most frequent
> sources of bugs, IMO, and the way it works is not intuitive
> and absolutely anti-C(D), in general.
>
> My suggestion of syntax:
>
>     select (n)
>     {
>         case (0)
>             foo();
>         case (1, 3, 7)
>         {
>             int m = foo(n);
>             bar(n);
>         }
>         case (2, 4 .. 6, 9)
>             bar(n);
>         default
>             throw new Error;
>     }
>
> This should deal with most switch() problems:
>
>     - no more break; only one case-block gets executed. Block statement
>       is required if there are more then one statement in case (just
>       like all other D constructs)
>     - easy to check for several possible values and/or ranges
>
> What do you think of this?
>
>


February 12, 2002
"Sean L. Palmer" <spalmer@iname.com> wrote in message news:a4arei$ude$1@digitaldaemon.com...
> Once break is no longer *required* in a switch, we can actually use break
to
> break out of an enclosing loop, something I've wished for many times in
the
> past.
>
> Sean

There is, in D, a break label construct enabling breaking out of any lexically enclosing loop.


February 12, 2002
Language behaviour should default to the behaviour that is most commonly
used and expected.  Hence there
should be an implicit break before each new case statement.  The fall
through behaviour of case can be omitted
entirely with the logical justification being that the fall through is not
part of the current case.

Fall though should also be avoided in my view because doing so would
facilitate converting the case statemement
from a standard branch around block type of code, to a more efficient
dispatch table type of code.

In the syntax above, bracketing is redundant.  The following syntax is superior

selectcase (a)
    case 1,2,3
    ...
    case 4,5,6
    ...
    case 7,8,9
    ...
    default
    ...
end select

Typically a compiler will comple the above code to.

_case1:   mov eax,a
              cmp eax,1
              je l1a
              cmp eax,2
               je l1a
               cmp eax,3
               jne l1
l1a:          <block1>
               jmp exit
l1:           cmp ax,4
               je l2a
               cmp  eax,5
               je l2a
               cmp  eax,6
               jne l2
l2a:          <block2>
               jmp exit
l2:            cmp eax,7
               je l3a
               cmp eax,8
               je l3a
               cmp eax,9
               jne dflt
l3a:          <block3>
               jmp exit
dflt:         <block4>
exit:         *

Without fallthrough the following code could be substituted....
This code will provide higher speed where the cases span a simple integer
sequence by
computing the jump address rather than performing multiple tests and jumps.

In the pervious example the worst case execution hits the default block
after 9 tests,
3 taken jumps and 6 aborted jumps.  In the code below,  it takes 2
unparallelable instructions
and one jump.  Other optimizations are possible.

case1:      mov  ebx,a
               sub   ebx,1
               cmp  ebx,9
               jae     dflt
               shl     ebx,2
               call    [dispatch + bx]
dflt:         <block4>
 exit:        *

diapatch:  &<block1>
                &<block2>
                &<block3>

l1:             <block1>
                 ret

l2:             <block2>
                 ret

l3:             <block3>
                 ret

I am not saying that D should provide this optimization.   But D should be thoughtful that such an optimization can be performed.

Mozilla contains a 10 page neted case statement in it's gif image compression parser.

Madness.

Walter <walter@digitalmars.com> wrote in message news:a4aril$ue9$1@digitaldaemon.com...
> The difficulty I have is I haven't had problems with switch in my own
code.
> I do like the idea of having multiple case values, though. The case range
is
> a good idea, too. I don't want to change the fall through behavior,
though.
> Is it really such a problem?



February 12, 2002
"Walter" <walter@digitalmars.com> wrote in message news:a4aril$ue9$1@digitaldaemon.com...

> The difficulty I have is I haven't had problems with switch in my own
code.

It's the matter of experience, I believe. All amateur C programmers,
especially those who came from other languages like BASIC or Pascal,
with strict select-case statement, tend to forget to add the break
at the end of case blocks. This is much like missing semicolons, but
the latter is detected at compile-time, while one occasionaly missed
break very often compiles silently and is then a source of hard-to-
catch bugs. After some practice, though, you get used to break out
of the cases - it took me about a month to polish my practical C skills
(including switch-breaks) when I moved to C from Pascal.

> I do like the idea of having multiple case values, though. The case range
is
> a good idea, too. I don't want to change the fall through behavior,
though.
> Is it really such a problem?

First of all, I suggest to leave the switch() construct untouched
(note that I proposed another keyword, select()), for some compatibility
with C, and for those [really rare] cases when you really need the
fall-through behaviour, like one in this piece of code (from WinD):

      case WM_LBUTTONDOWN:
          if (handleClicks)
              clicking = true;
      case WM_RBUTTONDOWN:
      case WM_MBUTTONDOWN:
          mouseDown(new MouseEvent(this, wParam, lParam));
          break;

However, such code is typically hard to read, because you might assume
there's a break statement where there isn't, or you might miss one
that is really there... so the _recommended_ way would be to use select(),
which is less prone for such errors.


February 12, 2002
"Sean L. Palmer" <spalmer@iname.com> wrote in message news:a4arei$ude$1@digitaldaemon.com...
> Once break is no longer *required* in a switch, we can actually use break
to
> break out of an enclosing loop, something I've wished for many times in
the
> past.

Yes, I also had it in mind when proposing this idea.


February 12, 2002
"Walter" <walter@digitalmars.com> wrote in message news:a4arl2$ueu$1@digitaldaemon.com...

> There is, in D, a break label construct enabling breaking out of any lexically enclosing loop.

True. But labels and goto (or break & continue w/label) make code somewhat harder to read - because you have to find that label to follow the execution flow of the program. If you're lucky enough to mess with the code written by one of those holy guys that use strict formatting rules (like me =)), you have a chance to see it easily:

    while(true)
    {
        switch()
        {
            ...
            break Out;
            ..
        }
    }
Out:
    ...

However, it's so easy to write this code in such a way you'll spend several minutes trying to find that damn Out in a 10-screen function listing. Not the most productive way to spend your time, it is. =)



February 12, 2002
I really think that this is a Good Idea...but that we do need a continuation block of some sort.  My favorite (of what's been proposed here) was "goto case":

select(n)
{
    case(0)
        foo();
    case(1,3,7)
    {
        int m = foo(n);
        goto case(2);
    }
    case(2,4..6,9)
        bar(n);
    default
        throw new Error;
}

--
The Villagers are Online! http://villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]


February 12, 2002
People have also talked about switches on strings or other types.  Frankly, I think that switches on arbitrary types is good, but switches on strings (i.e. arrays of chars and wchars) is almost "absolutely necessary". Trouble is, if you select() on an array, it's kind of ambiguous whether your're comparing the arrays (do the point to the same region and have the same length) or are you comparing the strings (would strcmp() return 0).  I think that the default behavior should be the latter...but that there should be a language construct for the former.  Maybe, like in setting arrays, we use the [] to tell the difference:

char string[] = ...;
select(string)
{
   ...   // compares arrays
}

select(string[])
{
    ... // compares array contents (i.e. the string value)
}

--
The Villagers are Online! http://villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]


« First   ‹ Prev
1 2 3 4 5 6 7 8