Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Can I jump to a case inside a switch using goto?

4,110 views
Skip to first unread message

rivkau...@gmail.com

unread,
Apr 2, 2014, 9:48:01 PM4/2/14
to

while((c=getchar())!=EOF){

switch(flower){
case rose:
switch(color){
case white:
// do something 1
case pink:
// do something 2
...
}
case lily:
switch(color){
case white:
// do something 1
case pink:
// do something 2

...
}
...
case unique:
// do something 3
...
}
}


basically, I can write the above statement completely using
if(flower==rose) goto
if(color==white) goto

type statements.

unfortunately, some of the flowers have strange names such as the ascii value of '/' or other characters like '%' and so on so switch-case gives me brevity.

However, inside switch-case I want to jump to certain cases before breaking to the end.

for example from (rose,pink) I may want to goto unique: . Can I do that by a

goto unique: ?

Note its a unique label. It is also an alias for another case where I want to do something unique before going into the while cycle which will read a char and then break down to the end.

I have a few choices.

One is that I have that label outside both of the switch-cases and its not a switch case label. There, if I want to fall through the cases below, I will have to use goto end: for all of them.

However, I can also put some dummy labels with break in the outermost switch-case and use them as labels.

In crux, the question is if I can use a switch-case's case-colon as a label for goto or not?

If so, then can I use a case like '%'-colon as a case for goto using

goto '%' ?

Thanks





Keith Thompson

unread,
Apr 2, 2014, 10:24:15 PM4/2/14
to
rivkau...@gmail.com writes:
[snip]
> In crux, the question is if I can use a switch-case's case-colon as a
> label for goto or not?
[snip]

No, you can't. The target of a goto must be a the name of a label
defined with the "identifer ": syntax; a case label doesn't qualify.

You can always add labels as needed:

switch (...) {
case 0:
L0:
/* ... */
break;
case 1:
L1:
/* ... */
break;
/* ... */
default:
Default:
/* ... */
break;
}
/* ... */
goto L1;
goto L2;
goto Default;

But I'd really advise you to rethink your design. Careful use of goto
statements, usually to a pointer *later* in the code, can be useful for
error handling and for breaking out of nested loops, but heavy use of
gotos can easily result in spaghetti code.

If you're implementing a finite state machine, I suggest either a switch
statement in a loop, where the switch executes some chunk of code
depending on the current state, *or* a sequence of labelled blocks with
gotos. (I personally prefer the former; for one thing, encoding the
current state in a variable rather than having it be implicit in the
current location in the program can be helpful). Mixing case labels and
gotos could easily get out of control.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

wil...@wilbur.25thandclement.com

unread,
Apr 2, 2014, 11:02:17 PM4/2/14
to
Keith Thompson <ks...@mib.org> wrote:
> rivkau...@gmail.com writes:
> [snip]
>> In crux, the question is if I can use a switch-case's case-colon as a
>> label for goto or not?
> [snip]
>
> No, you can't. The target of a goto must be a the name of a label
> defined with the "identifer ": syntax; a case label doesn't qualify.
>
> You can always add labels as needed:
<snip>
> If you're implementing a finite state machine, I suggest either a switch
> statement in a loop, where the switch executes some chunk of code
> depending on the current state, *or* a sequence of labelled blocks with
> gotos. (I personally prefer the former; for one thing, encoding the
> current state in a variable rather than having it be implicit in the
> current location in the program can be helpful). Mixing case labels and
> gotos could easily get out of control.

It's a shame the committee never took up computed gotos. For complex state
machines you often need to jump around. Sure, you can set the next state and
break out of the switch statement. But often times code will be nested
inside loops, so you need to use a goto, anyhow, to break out. And that goto
often takes you back to the _top_ of some outer loop.

Plus, if you care about performance, you want to try to thread your
instructions to avoid the loop conditional. I suppose it's possible with
switch statements, as long as your compiler is smart enough, but computed
gotos make it so much easier.

I've had some success with macro solutions which hide two
implementations--one using switch and another computed gotos. With GCC and
clang computed goto machines are always significantly faster. (And I never
use GCC's recommendation of storing label offsets, because that's a gigantic
pain in the butt--impossible if you generate cases or labels with
__LINE__--and in the age of C++ nobody will notice the insignicant link-time
costs.)

rivkau...@gmail.com

unread,
Apr 3, 2014, 2:04:00 AM4/3/14
to
On Wednesday, April 2, 2014 8:02:17 PM UTC-7, wil...@wilbur.25thandClement.com wrote:
> Keith Thompson <ks...@mib.org> wrote:
>
> > riv...@gmail.com writes:
>
> > [snip]
>
> >> In crux, the question is if I can use a switch-case's case-colon as a
>
> >> label for goto or not?
>
> > [snip]
>
> >
>
> > No, you can't. The target of a goto must be a the name of a label
>
> > defined with the "identifer ": syntax; a case label doesn't qualify.
>
> >
>
> > You can always add labels as needed:
>
> <snip>
>
> > If you're implementing a finite state machine, I suggest either a switch
>
> > statement in a loop, where the switch executes some chunk of code
>
> > depending on the current state, *or* a sequence of labelled blocks with
>
> > gotos. (I personally prefer the former; for one thing, encoding the
>
> > current state in a variable rather than having it be implicit in the
>
> > current location in the program can be helpful). Mixing case labels and
>
> > gotos could easily get out of control.
>

Wil... , you seem to cover a number of topics rapidly in your reply. Unfortunately, google does not give an option to email you either.

What is computed goto and which languages have it?

>
> It's a shame the committee never took up computed gotos. For complex state
>
> machines you often need to jump around. Sure, you can set the next state and
>
> break out of the switch statement. But often times code will be nested
>
> inside loops, so you need to use a goto, anyhow, to break out. And that goto
>
> often takes you back to the _top_ of some outer loop.
>

I wanted to see some examples.

>
> Plus, if you care about performance, you want to try to thread your
>
> instructions to avoid the loop conditional. I suppose it's possible with
>
> switch statements, as long as your compiler is smart enough, but computed
>
> gotos make it so much easier.
>

Again some concrete examples would clarify the vision in your mind.

>
> I've had some success with macro solutions which hide two

specific macros and the example?

> implementations--one using switch and another computed gotos. With GCC and
>
> clang computed goto machines are always significantly faster. (And I never
>
> use GCC's recommendation of storing label offsets, because that's a gigantic
>
> pain in the butt--impossible if you generate cases or labels with
>
> __LINE__--and in the age of C++ nobody will notice the insignicant link-time
>
> costs.)

Again, more writing is needed to clarify your point and generate benefit.

rivkau...@gmail.com

unread,
Apr 3, 2014, 2:08:50 AM4/3/14
to
On Wednesday, April 2, 2014 7:24:15 PM UTC-7, Keith Thompson wrote:
Thanks. I understood all your points except this one.

"for one thing, encoding the
>
> current state in a variable rather than having it be implicit in the
>
> current location in the program can be helpful)"

How can it be helpful? what are the comparative limitations of each approach?

Second, can you try to make sense of the points made by wil... , the next poster?
Message has been deleted

JohnF

unread,
Apr 3, 2014, 2:36:50 AM4/3/14
to
Keith Thompson <ks...@mib.org> wrote:
> rivkau...@gmail.com writes:
> [snip]
>> can I use a switch-case's case-colon as a
>> label for goto or not?
> [snip]
>
> No, you can't.
> You can always add labels as needed:
> switch (...) {
> case 0:
> L0: /* ... */ break;
> case 1:
> L1: /* ... */ break;
> /* ... */
> default:
> Default: /* ... */ break;
> } /* --- end-of-switch() --- */
> /* ... */
> goto L0;
> goto L1;
> goto Default;
> But I'd really advise you to rethink your design.

Yeah, that's for sure. But just curious -- if one
of those goto's takes execution from outside the
switch's {...} to inside it, will the subsequent
break understand the scope, i.e., where the program
counter should go next? And is that behavior mandated
by standard?
--
John Forkosh ( mailto: j...@f.com where j=john and f=forkosh )
Message has been deleted

rivkau...@gmail.com

unread,
Apr 3, 2014, 3:18:26 AM4/3/14
to
On Wednesday, April 2, 2014 11:31:03 PM UTC-7, Stefan Ram wrote:
> riv...@gmail.com writes:
>
> >Can I jump to a case inside a switch using goto?
>
> #include <stdio.h>
> int main()
> { int pc = 3;
> #define GOTO(x) pc=x;break
>
> while( 1 )switch( pc )
> { case 2: puts( "2:" ); goto out;
> case 3: puts( "3:" ); GOTO( 2 ); }
> out:; }

> >Can I jump to a case inside a switch using goto?

but you are going through the while loop head to do the GOTO.
In my case, there is a getchar() there so an input stream has been consumed. You are not allowed to go through the loop head.

glen herrmannsfeldt

unread,
Apr 3, 2014, 3:51:08 AM4/3/14
to
rivkau...@gmail.com wrote:
> On Wednesday, April 2, 2014 8:02:17 PM UTC-7, wil...@wilbur.25thandClement.com wrote:
(snip)

> What is computed goto and which languages have it?

As far as I know, it started with Fortran I in 1956.

GOTO (10, 20, 30, 40, 50, 60), J

Goes to the first statement number if J is 1, the second if J is 2,
and so on. In early Fortran (before 1977) it was undefined if J
was less than 1 or greater than the number of labels. Many as an
extension, and added in Fortran 77, if J is out of range, it goes
to the following statement.

Many BASIC systems implement computed GOTO as

100 ON J GOTO 10, 20, 30, 40, 50, 60

PL/I has LABEL variable arrays, which can either be initialized
with the appropriate labels on the DECLARE, or by specifying an
array element as a statement label. The latter doesn't look so
different from switch/case.

DCL X(5) LABEL INITIAL(ONE, TWO, THREE);

or:

DCL Y(5) LABEL;

then label statements such as:

Y(3): PUT LIST('Three');


Then GOTO X(I); or GOTO Y(J); will go to the appropriate statement.

I think ALGOL-68 has one, but I am not sure. The description is
in its own language, and not so easy to figure out.

As I happen to have a COBOL manual nearby, though haven't actually
written any programs, it seems to have:

GOTO labels DEPENDING ON variable.


-- glen

Message has been deleted

Malcolm McLean

unread,
Apr 3, 2014, 4:20:50 AM4/3/14
to
On Thursday, April 3, 2014 7:04:00 AM UTC+1, rivkau...@gmail.com wrote:
>
>
> What is computed goto and which languages have it?
>
Fortran has it.
Minibasic http://sourceforge.net/directory/?q=minibasic also has it.

You use integers for lablels, then goto x; is allowed, where x is an integer
variable. In Minibasic, is was a simply a case of writing the parser as
goto (expression) rather than goto (number). But I rather regret allowing it,
because it made writing the optimised version of the interpreter a lot more
difficult.

Switch is a bit slow in a deeply nested loop. For example, when you're
emulating a processor in C, you need to switch on the instruction. That's
often the rate-limiting step in the program. A computed goto can often
prove faster (shift the instruction up four bits, add to the base, jump,
and make sure all your ops are exactly 16 instructions long).

BartC

unread,
Apr 3, 2014, 4:39:02 AM4/3/14
to


"glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
news:lhj3tc$5kd$1...@speranza.aioe.org...
> rivkau...@gmail.com wrote:
>> On Wednesday, April 2, 2014 8:02:17 PM UTC-7,
>> wil...@wilbur.25thandClement.com wrote:
> (snip)
>
>> What is computed goto and which languages have it?
>
> As far as I know, it started with Fortran I in 1956.
>
> GOTO (10, 20, 30, 40, 50, 60), J

So what's the difference between that, and:

switch (J) {
case 1:
case 2:
....
case 6:
?

> I think ALGOL-68 has one, but I am not sure. The description is
> in its own language, and not so easy to figure out.

More than likely; you'd just have a row of labels, and perhaps use it
directly as in goto (L1,L2,L3)[J].

But it also has case in... out.

--
Bartc

BartC

unread,
Apr 3, 2014, 4:49:45 AM4/3/14
to
<rivkau...@gmail.com> wrote in message
news:1af492a6-6797-401a...@googlegroups.com...

> case unique:
> // do something 3
> ...
> }
> }
>
>
> basically, I can write the above statement completely using
> if(flower==rose) goto
> if(color==white) goto
>
> type statements.
>
> unfortunately, some of the flowers have strange names such as the ascii
> value of '/' or other characters like '%' and so on so switch-case gives
> me brevity.
>
> However, inside switch-case I want to jump to certain cases before
> breaking to the end.
>
> for example from (rose,pink) I may want to goto unique: . Can I do that by
> a
>
> goto unique: ?

Another way to share code between cases is to put it in functions.

So if the code for unique is in dosomething3(), then from rose,pink you just
call dosomething3(). No need for a goto.

--
Bartc

Ben Bacarisse

unread,
Apr 3, 2014, 6:52:00 AM4/3/14
to
"BartC" <b...@freeuk.com> writes:

> "glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
> news:lhj3tc$5kd$1...@speranza.aioe.org...
<snip>
>> I think ALGOL-68 has one, but I am not sure. The description is
>> in its own language, and not so easy to figure out.
>
> More than likely; you'd just have a row of labels, and perhaps use it
> directly as in goto (L1,L2,L3)[J].

Not exactly. A label evaluates to a procedure (of mode PROC VOID) so
you can make a row of them, but you have to "call" the procedure, rather
than use goto directly.

[] PROC VOID labels = (L1, L2, L3);
...
labels[j];

> But it also has case in... out.

or rather "case in ... out ... esac".

--
Ben.

Paul N

unread,
Apr 3, 2014, 7:15:28 AM4/3/14
to
In BCPL, labels were numbers just like any other variable. So you could do:

GOTO val -> lab1 , lab2

to choose one of two targets ( -> is the BCPL equivalent of ? : )

or you could use an array; or you could even do

GOTO lab + 4

if jumping to slightly after a label is your idea of fun.

Kenny McCormack

unread,
Apr 3, 2014, 7:33:49 AM4/3/14
to
In article <d2d61fb2-b51f-498b...@googlegroups.com>,
Paul N <gw7...@aol.com> wrote:
...
>In BCPL, labels were numbers just like any other variable. So you could do:
>
>GOTO val -> lab1 , lab2
>
>to choose one of two targets ( -> is the BCPL equivalent of ? : )
>
>or you could use an array; or you could even do
>
>GOTO lab + 4
>
>if jumping to slightly after a label is your idea of fun.

Note, incidentally, that you *can* implement computed goto in C - in fact,
in entirely standard (on topic) C. The details of how to do it escape me
at the moment, but it involves setjmp and longjmp. Basically, you set up
an array of jmpbufs and then longjmp to the one you want. Somebody figured
this out and explained it to me sometime back in the 80s.

Perhaps someone here will take it on as a challenge...

--
Atheism:
It's like being the only sober person in the car, and nobody will let you drive.

Richard

unread,
Apr 3, 2014, 7:38:47 AM4/3/14
to
gaz...@shell.xmission.com (Kenny McCormack) writes:

> In article <d2d61fb2-b51f-498b...@googlegroups.com>,
> Paul N <gw7...@aol.com> wrote:
> ...
>>In BCPL, labels were numbers just like any other variable. So you could do:
>>
>>GOTO val -> lab1 , lab2
>>
>>to choose one of two targets ( -> is the BCPL equivalent of ? : )
>>
>>or you could use an array; or you could even do
>>
>>GOTO lab + 4
>>
>>if jumping to slightly after a label is your idea of fun.
>
> Note, incidentally, that you *can* implement computed goto in C - in fact,
> in entirely standard (on topic) C. The details of how to do it escape me
> at the moment, but it involves setjmp and longjmp. Basically, you set up
> an array of jmpbufs and then longjmp to the one you want. Somebody figured
> this out and explained it to me sometime back in the 80s.
>
> Perhaps someone here will take it on as a challenge...

Now you've done it.

--
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c

BartC

unread,
Apr 3, 2014, 7:42:35 AM4/3/14
to
"Ben Bacarisse" <ben.u...@bsb.me.uk> wrote in message
news:0.14b58597798c773ac5d7.2014...@bsb.me.uk...
> "BartC" <b...@freeuk.com> writes:
>
>> "glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message

>>> I think ALGOL-68 has one, but I am not sure. The description is
>>> in its own language, and not so easy to figure out.
>>
>> More than likely; you'd just have a row of labels, and perhaps use it
>> directly as in goto (L1,L2,L3)[J].
>
> Not exactly. A label evaluates to a procedure (of mode PROC VOID) so
> you can make a row of them, but you have to "call" the procedure, rather
> than use goto directly.
>
> [] PROC VOID labels = (L1, L2, L3);
> ...
> labels[j];

I've just tried it, and you're right. But like this, it's not quite as
succinct. (I base my own syntaxes on A68; with a dynamic language, I can
actually write goto (L1,L2,L3)[J], but will also need goto labels[j] for a
static one. In both cases though I insist on 'goto' to make it clear what
this is.)

But, the fact that A68 treats such a label as a kind of local proc name
gives me an idea for an idea for a language feature that might help the OP
(if it could somehow be implemented today in C).

This is a lightweight call that would pass control to a labelled block
somewhere in this function, just like goto, but then returns at the end of
the block. Access to all local variables is maintained as normal.
Encountering the block also executes it as normal:

rose:
dosomething2();
gosub dosomething3; // use gosub rather than goto or ()
...
unique:
dosomething3:{
.....
}

Well, it's an idea ...

--
Bartc

James Kuyper

unread,
Apr 3, 2014, 7:48:37 AM4/3/14
to
On 04/03/2014 02:36 AM, JohnF wrote:
> Keith Thompson <ks...@mib.org> wrote:
...
>> You can always add labels as needed:
>> switch (...) {
>> case 0:
>> L0: /* ... */ break;
>> case 1:
>> L1: /* ... */ break;
>> /* ... */
>> default:
>> Default: /* ... */ break;
>> } /* --- end-of-switch() --- */
>> /* ... */
>> goto L0;
>> goto L1;
>> goto Default;
>> But I'd really advise you to rethink your design.
>
> Yeah, that's for sure. But just curious -- if one
> of those goto's takes execution from outside the
> switch's {...} to inside it, will the subsequent
> break understand the scope, i.e., where the program
> counter should go next? And is that behavior mandated
> by standard?

"A break statement terminates execution of the smallest enclosing switch
or iteration statement." (6.8.6.3p2) It doesn't matter how execution of
the program reached the break statement, the only thing that matters is
the location of the break statement.
--
James Kuyper

JohnF

unread,
Apr 3, 2014, 8:21:35 AM4/3/14
to
Thanks, James. I hadn't been aware of that before.
But after posting, I realized I hadn't exactly asked
the complete question that bothered me. Consider the
following snippet,
char label[100] = "printed during loop";
int nloop = 0;
while ( 1 ) {
int i = 0;
entry_pt:
i++;
printf("%s: i=%d\n",label,i);
if ( i >= 10 ) break;
} /* --- continue --- */
if ( ++nloop < 2 ) {
strcpy(label,"printed after goto");
goto entry_pt; }
Okay, so you know the question: what's the
value of i "printed after goto"? And what's the
general rule about that? And how portable is it?
Thanks,

James Kuyper

unread,
Apr 3, 2014, 10:16:29 AM4/3/14
to
On 04/03/2014 08:21 AM, JohnF wrote:
> James Kuyper <james...@verizon.net> wrote:
...
>> "A break statement terminates execution of the smallest enclosing switch
>> or iteration statement." (6.8.6.3p2) It doesn't matter how execution of
>> the program reached the break statement, the only thing that matters is
>> the location of the break statement.
>
> Thanks, James. I hadn't been aware of that before.
> But after posting, I realized I hadn't exactly asked
> the complete question that bothered me. Consider the
> following snippet,
> char label[100] = "printed during loop";
> int nloop = 0;
> while ( 1 ) {
> int i = 0;
> entry_pt:
> i++;
> printf("%s: i=%d\n",label,i);
> if ( i >= 10 ) break;
> } /* --- continue --- */
> if ( ++nloop < 2 ) {
> strcpy(label,"printed after goto");
> goto entry_pt; }
> Okay, so you know the question: what's the
> value of i "printed after goto"? And what's the
> general rule about that? And how portable is it?
> Thanks,

The goto statement enters the block containing the definition of 'i', so
a new instance of i is created with an indeterminate value. The goto
skips the initialization of i, which therefore doesn't occur. At least,
that's how I interpret 6.2.4p6. If the indeterminate value of i is
either a trap representation or INT_MAX, the i++ expression renders the
behavior of the entire program undefined. Otherwise, the value of 'i' is
unspecified, but valid, after the jump. In that case, the increment
occurs normally, and INT_MIN < i && i <= INT_MAX at the time of the
printf() call.

If you want i to have a well-defined value after the goto, move the
label before the declaration of i, or make i static.
--
James Kuyper

Keith Thompson

unread,
Apr 3, 2014, 11:04:52 AM4/3/14
to
"BartC" <b...@freeuk.com> writes:
[...]
> But, the fact that A68 treats such a label as a kind of local proc name
> gives me an idea for an idea for a language feature that might help the OP
> (if it could somehow be implemented today in C).
>
> This is a lightweight call that would pass control to a labelled block
> somewhere in this function, just like goto, but then returns at the end of
> the block. Access to all local variables is maintained as normal.
> Encountering the block also executes it as normal:
>
> rose:
> dosomething2();
> gosub dosomething3; // use gosub rather than goto or ()
> ...
> unique:
> dosomething3:{
> .....
> }
>
> Well, it's an idea ...

gcc supports nested functions as an extension, which strike me as a
cleaner way to do the same thing. The only difference would be that a
goto can't (as far as I know) jump from one function to another, even if
one is nested in the other, but I don't think that's a disadvantage.

Keith Thompson

unread,
Apr 3, 2014, 11:09:19 AM4/3/14
to
rivkau...@gmail.com writes:
> On Wednesday, April 2, 2014 7:24:15 PM UTC-7, Keith Thompson wrote:
>> riv...@gmail.com writes:
[...]
>> If you're implementing a finite state machine, I suggest either a switch
>> statement in a loop, where the switch executes some chunk of code
>> depending on the current state, *or* a sequence of labelled blocks with
>> gotos. (I personally prefer the former; for one thing, encoding the
>> current state in a variable rather than having it be implicit in the
>> current location in the program can be helpful). Mixing case labels and
>> gotos could easily get out of control.
>
> Thanks. I understood all your points except this one.
> "for one thing, encoding the
>> current state in a variable rather than having it be implicit in the
>> current location in the program can be helpful)"
>
> How can it be helpful? what are the comparative limitations of each
> approach?

It can make debugging easier. You can print the value of the state
variable on each iteration of the loop, either by setting a single
breakpoint or by adding a single printf() call. If you want to trace
every state transition in an FSM implemented with gotos, you have to add
code to every state.

Keith Thompson

unread,
Apr 3, 2014, 11:12:30 AM4/3/14
to
James Kuyper <james...@verizon.net> writes:
[...]
> If you want i to have a well-defined value after the goto, move the
> label before the declaration of i, or make i static.

Though C has permitted mixed declarations and statements since C99, it
still doesn't permit labels on declarations. This:

label: int i = 0;

is a syntax error. (I just ran into this the other day.)

You can just add a null statement:

label:; int i = 0;

glen herrmannsfeldt

unread,
Apr 3, 2014, 11:59:58 AM4/3/14
to
Keith Thompson <ks...@mib.org> wrote:
> "BartC" <b...@freeuk.com> writes:
(snip on Algol-68 feature)

>> This is a lightweight call that would pass control to a labelled block
>> somewhere in this function, just like goto, but then returns at the end of
>> the block. Access to all local variables is maintained as normal.
>> Encountering the block also executes it as normal:

>> rose:
>> dosomething2();
>> gosub dosomething3; // use gosub rather than goto or ()
>> ...
>> unique:
>> dosomething3:{
>> .....
>> }

>> Well, it's an idea ...

> gcc supports nested functions as an extension, which strike me as a
> cleaner way to do the same thing. The only difference would be that a
> goto can't (as far as I know) jump from one function to another, even if
> one is nested in the other, but I don't think that's a disadvantage.

Pascal and PL/I allow GOTO out of internal functions, but not in.
In PL/I, you can do it with label variables.

C has longjmp() if you really want to do it.

-- glen

James Kuyper

unread,
Apr 3, 2014, 12:44:11 PM4/3/14
to
On 04/03/2014 11:12 AM, Keith Thompson wrote:
> James Kuyper <james...@verizon.net> writes:
> [...]
>> If you want i to have a well-defined value after the goto, move the
>> label before the declaration of i, or make i static.
>
> Though C has permitted mixed declarations and statements since C99, it
> still doesn't permit labels on declarations. This:
>
> label: int i = 0;
>
> is a syntax error. (I just ran into this the other day.)
>
> You can just add a null statement:
>
> label:; int i = 0;

That's what I actually meant, though I didn't say it quite right.

Lowell Gilbert

unread,
Apr 3, 2014, 2:24:05 PM4/3/14
to
Ben Bacarisse <ben.u...@bsb.me.uk> writes:

> "BartC" <b...@freeuk.com> writes:
>
>> "glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
>> news:lhj3tc$5kd$1...@speranza.aioe.org...
> <snip>
>>> I think ALGOL-68 has one, but I am not sure. The description is
>>> in its own language, and not so easy to figure out.
>>
>> More than likely; you'd just have a row of labels, and perhaps use it
>> directly as in goto (L1,L2,L3)[J].
>
> Not exactly. A label evaluates to a procedure (of mode PROC VOID) so
> you can make a row of them, but you have to "call" the procedure, rather
> than use goto directly.
>
> [] PROC VOID labels = (L1, L2, L3);
> ...
> labels[j];

But that's just a funtion table, which is
even more common in these types of languages...

--
Lowell Gilbert, embedded/networking software engineer
http://be-well.ilk.org/~lowell/
Message has been deleted

rivkau...@gmail.com

unread,
Apr 3, 2014, 5:56:26 PM4/3/14
to
On Wednesday, April 2, 2014 8:02:17 PM UTC-7, wil...@wilbur.25thandClement.com wrote:
> Keith Thompson <ks...@mib.org> wrote:
>
> > riv...@gmail.com writes:
>
> > [snip]
>
> >> In crux, the question is if I can use a switch-case's case-colon as a
>
> >> label for goto or not?
>
> > [snip]
>
> >
>
> > No, you can't. The target of a goto must be a the name of a label
>
> > defined with the "identifer ": syntax; a case label doesn't qualify.
>
> >
>
> > You can always add labels as needed:
>
> <snip>
>
> > If you're implementing a finite state machine, I suggest either a switch
>
> > statement in a loop, where the switch executes some chunk of code
>
> > depending on the current state, *or* a sequence of labelled blocks with
>
> > gotos. (I personally prefer the former; for one thing, encoding the
>
> > current state in a variable rather than having it be implicit in the
>
> > current location in the program can be helpful). Mixing case labels and
>
> > gotos could easily get out of control.
>

There is a phenomenal amount of content in this thread, could you just give a 10 sentence summary of the consensus - if one exists?

Could you reword and expand claims in your post below by real examples where I indicate a need for clarity?

>
> It's a shame the committee never took up computed gotos. For complex state
>
> machines you often need to jump around. Sure, you can set the next state and
>
> break out of the switch statement. But often times code will be nested
>
> inside loops, so you need to use a goto, anyhow, to break out. And that goto
>
> often takes you back to the _top_ of some outer loop.
>
>
>
> Plus, if you care about performance, you want to try to thread your
>
> instructions to avoid the loop conditional. I suppose it's possible with
>
> switch statements, as long as your compiler is smart enough, but computed
>
> gotos make it so much easier.
>
>
>
> I've had some success with macro solutions which hide two
>
> implementations--one using switch and another computed gotos.

Could you or someone else give a real example?

> With GCC and
>
> clang computed goto machines are always significantly faster. (And I never
>
> use GCC's recommendation of storing label offsets, because that's a gigantic
>
> pain in the butt--impossible if you generate cases or labels with
>
> __LINE__--and in the age of C++ nobody will notice the insignicant link-time
>
> costs.)

Again, could you or someone else give a real example?

JohnF

unread,
Apr 4, 2014, 3:06:49 AM4/4/14
to
Thanks for additional clarification, James (and for not
pointing out how my i++ was pretty darned useless:).
That seems to just emphasize the earlier judgement that
this kind of branch is more than likely a bad thing.

Ben Bacarisse

unread,
Apr 4, 2014, 6:06:12 PM4/4/14
to
Lowell Gilbert <lgus...@be-well.ilk.org> writes:

> Ben Bacarisse <ben.u...@bsb.me.uk> writes:
>
>> "BartC" <b...@freeuk.com> writes:
>>
>>> "glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message
>>> news:lhj3tc$5kd$1...@speranza.aioe.org...
>> <snip>
>>>> I think ALGOL-68 has one, but I am not sure. The description is
>>>> in its own language, and not so easy to figure out.
>>>
>>> More than likely; you'd just have a row of labels, and perhaps use it
>>> directly as in goto (L1,L2,L3)[J].
>>
>> Not exactly. A label evaluates to a procedure (of mode PROC VOID) so
>> you can make a row of them, but you have to "call" the procedure, rather
>> than use goto directly.
>>
>> [] PROC VOID labels = (L1, L2, L3);
>> ...
>> labels[j];
>
> But that's just a funtion table, which is
> even more common in these types of languages...

Yes, it looks like a function table but it's not quite the same as one.
For one thing, the values don't actually derive from functions, and they
also become invalid if the table is returned form the function that
contains the labels.

--
Ben.

Ben Bacarisse

unread,
Apr 4, 2014, 6:22:59 PM4/4/14
to
Paul N <gw7...@aol.com> writes:

> On Thursday, 3 April 2014 08:51:08 UTC+1, glen herrmannsfeldt wrote:
>> rivkau...@gmail.com wrote:
>> > On Wednesday, April 2, 2014 8:02:17 PM UTC-7, wil...@wilbur.25thandClement.com wrote:
>> (snip)
>>
>> > What is computed goto and which languages have it?
>>
>> As far as I know, it started with Fortran I in 1956.
>>
>> GOTO (10, 20, 30, 40, 50, 60), J
<snip>
> In BCPL, labels were numbers just like any other variable. So you could do:
>
> GOTO val -> lab1 , lab2
>
> to choose one of two targets ( -> is the BCPL equivalent of ? : )
>
> or you could use an array; or you could even do
>
> GOTO lab + 4
>
> if jumping to slightly after a label is your idea of fun.

There's two kinds of "computed" here: the index into a list of labels
and the label list itself. In Fortran, the list was static --
effectively a literal array -- and only the index is "computed". That
kind of computed goto can be done in C:

switch (J) { case 1: goto L1; case 2: goto L2; ... }

It's clumsy to write, but the functionality is there (though I'm blessed
never to have see it used!).

In BCPL and in Algol 68 (and C with gcc's extensions) you can compute
with the labels themselves, though there may be very severe
restrictions on exactly what you can do. Once you can play with the
value of a label in some way (however limited) you get more
opportunities for "fun".

--
Ben.

Tim Rentsch

unread,
Apr 14, 2014, 7:38:46 PM4/14/14
to
This analysis is right for C90 and C99. In C11, the access
is i is simply undefined behavior, under 6.3.2.1 p2.
0 new messages