You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
gotocase: a case for useful and not harmful goto #5950
While it's obvious that goto is considered harmful, sometimes it is still a usefull tool.
Because zig dosen't support switch falltrough, i propose an alternative: gotocase.
Let's consider this esample from https://wiki.c2.com/?GoTo in C
Mask *pMask(NULL); switch (type) {
case POINT:
Mask tmpMask;
vector<Location> &v=getVectorOfPoints();
for (iterator it=v.begin();it!=v.end();++it)
tmpMask.set(*it);
pMask = &tmpMask;
goto drawMask;
case MASK:
pMask=getBitMask();
drawMask:
// here's the code to draw the mask overlay
break;
}
This obviously saves time and looks more elegant than combination of if statements and functions.
Perhaps with gotocase it could look like this:
switch (type) {
POINT =>
//dopointstuff
gotocase else;
MASK =>
pMask=getBitMask();
gotocase else;
else =>
// here's the code to draw the mask overlay
}
To enforce good code practices one could restrict gotocase to apear only at the end of the case and only cases that are further down.
gotocase, as far as I can see, is there for removing code duplication in situations where multiple cases of a switch contain very similar (almost exact) statements.
Furthermore, a prominent example of the linked website on the first issue comment displays the usage of goto in FSM-based lexers. I actually don't think lexers using that are better. This makes understanding them a more tedious task. If there is not only the obvious way I can jump into a switch case, but also non-obvious ways (jumped from other cases), where did I come from? What does this case really do? The best counterexamples for the necessity of lexers with gotocase are the lexers for zig and C in the standard library.
// In C
int interp_goto(unsigned char* code, int initval) {
/* The indices of labels in the dispatch_table are the relevant opcodes*/
static void* dispatch_table[] = { &&do_halt, &&do_inc, &&do_dec};
#define DISPATCH() goto *dispatch_table[code[pc++]]
int pc = 0;
int val = initval;
DISPATCH();
while (1) {
do_halt:
return val;
do_inc:
val++;
DISPATCH();
do_dec:
val--;
DISPATCH();
}
}
Where it would allow us to express the above with something like
Activity
joachimschmidt557 commentedon Jul 29, 2020
I think the more idiomatic zig way for handling that example would be to define
pmaskwith a switch:joachimschmidt557 commentedon Jul 30, 2020
gotocase, as far as I can see, is there for removing code duplication in situations where multiple cases of aswitchcontain very similar (almost exact) statements.If they were exactly the same, we could just combine them.
But we can solve this problem without needing
gotocase.Furthermore, a prominent example of the linked website on the first issue comment displays the usage of
gotoin FSM-based lexers. I actually don't think lexers using that are better. This makes understanding them a more tedious task. If there is not only the obvious way I can jump into a switch case, but also non-obvious ways (jumped from other cases), where did I come from? What does this case really do? The best counterexamples for the necessity of lexers withgotocaseare the lexers for zig and C in the standard library.pixelherodev commentedon Jul 30, 2020
ekipan commentedon Aug 4, 2020
So,
continue! Switches alreadybreak, after all.joachimschmidt557 commentedon Aug 4, 2020
@ekipan, as I mentioned in my comment earlier, what you wrote can be achieved without
continuein the current zig syntax:ekipan commentedon Aug 4, 2020
@joachimschmidt557 Sure, I was just talking syntax though. I've no opinion on the feature itself. Multicase prongs can't do this:
But again you could just use functions:
raulgrell commentedon Aug 4, 2020
The use case I thought this was going to address is implementing something like computed
gotos, described here: https://eli.thegreenplace.net/2012/07/12/computed-goto-for-efficient-dispatch-tablesWhere it would allow us to express the above with something like
On one hand we lose the cue from "while" that there is effectively a loop.
andrewrk commentedon Aug 23, 2021
The use case in this proposal is sufficiently addressed by the comments in this issue as well as #8220.