473,382 Members | 1,480 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,382 software developers and data experts.

Howto "goto address_x;"

Before I start, please let's not discuss whether goto is evil or not.
For generated code, this can make perfect sense.

It would be interesting to know a trick how to get C to do a goto to
an address that has been assigned to a variable, i.e.

MyLabel:
....
address_x = MyLabel;
....
goto address_x;
I tried to pack the positions into a switch statement and made
'address_x' a variable of type 'enum', such as

enum { Label1, Label2, Label3, ... } address_x;

GotoStartPoint:
switch( address_x ) {
case Label1: ...
case Label2: ...
case Label3: ...
}
....
address_x = Label2;
goto GotoStartPoint;

But when I look at the assembler code, it is not as efficient as a
jump to an address assigned to a variable.

Is there any way to get arround that?

Best Regards

Frank
Jan 4 '08 #1
15 3085
Frank wrote:
It would be interesting to know a trick how to get C to do a goto to
an address that has been assigned to a variable, i.e.
(snip somewhat confusing code).

What are you /actually/ trying to achieve ? The snipped code looks like
an attempt to solve some problem or other which you haven't explained.
Jan 4 '08 #2
On Jan 4, 12:49*am, Frank <fsch...@googlemail.comwrote:
Before I start, *please let's not discuss whether goto is evil or not.
For generated code, this can make perfect sense.

It would be interesting to know a trick how to get C to do a goto to
an address that has been assigned to a variable, i.e.

MyLabel:
...
* * *address_x = MyLabel;
...
* * *goto address_x;

I tried to pack the positions into a switch statement and made
'address_x' a variable of type 'enum', such as

enum { Label1, Label2, Label3, ... } address_x;

GotoStartPoint:
switch( address_x ) {
case Label1: ...
case Label2: ...
case Label3: ...}

...
address_x = Label2;
goto GotoStartPoint;

But when I look at the assembler code, it is not as efficient as a
jump to an address assigned to a variable.

Is there any way to get arround that?
Before writing coroutines, ask yourself, "Is it really worth it?"
After all, someone is going to have to maintain it.

Anyway, this will show you what you are after:
http://www.google.com/search?hl=en&q=coroutines
Jan 4 '08 #3

"Frank" <fs*****@googlemail.comwrote in message
news:a2**********************************@e6g2000p rf.googlegroups.com...
Before I start, please let's not discuss whether goto is evil or not.
For generated code, this can make perfect sense.

It would be interesting to know a trick how to get C to do a goto to
an address that has been assigned to a variable, i.e.

MyLabel:
...
address_x = MyLabel;
...
goto address_x;
I tried to pack the positions into a switch statement and made
'address_x' a variable of type 'enum', such as

enum { Label1, Label2, Label3, ... } address_x;

GotoStartPoint:
switch( address_x ) {
case Label1: ...
case Label2: ...
case Label3: ...
}
...
address_x = Label2;
goto GotoStartPoint;

But when I look at the assembler code, it is not as efficient as a
jump to an address assigned to a variable.

Is there any way to get arround that?

Best Regards

Frank
GNU C has the extension of label variables and allows you to jump to any
such evaluated address.

Labels as Values
================

You can get the address of a label defined in the current function
(or a containing function) with the unary operator `&&'. The value has
type `void *'. This value is a constant and can be used wherever a
constant of that type is valid. For example:

void *ptr;
/* ... */
ptr = &&foo;

To use these values, you need to be able to jump to one. This is
done with the computed goto statement(1), `goto *EXP;'. For example,

goto *ptr;

Any expression of type `void *' is allowed.

One way of using these constants is in initializing a static array
that will serve as a jump table:

static void *array[] = { &&foo, &&bar, &&hack };

Then you can select a label with indexing, like this:

goto *array[i];
Jan 4 '08 #4

"Ravishankar S" <ra***********@in.bosch.comwrote in message
news:fl**********@news4.fe.internet.bosch.com...
>
"Frank" <fs*****@googlemail.comwrote in message
news:a2**********************************@e6g2000p rf.googlegroups.com...
Before I start, please let's not discuss whether goto is evil or not.
For generated code, this can make perfect sense.

It would be interesting to know a trick how to get C to do a goto to
an address that has been assigned to a variable, i.e.

MyLabel:
...
address_x = MyLabel;
...
goto address_x;
I tried to pack the positions into a switch statement and made
'address_x' a variable of type 'enum', such as

enum { Label1, Label2, Label3, ... } address_x;

GotoStartPoint:
switch( address_x ) {
case Label1: ...
case Label2: ...
case Label3: ...
}
...
address_x = Label2;
goto GotoStartPoint;

But when I look at the assembler code, it is not as efficient as a
jump to an address assigned to a variable.

Is there any way to get arround that?

Best Regards

Frank

GNU C has the extension of label variables and allows you to jump to any
such evaluated address.
I forgot the disclaimer :) : Its completely non-standard !
>
Labels as Values
================

You can get the address of a label defined in the current function
(or a containing function) with the unary operator `&&'. The value has
type `void *'. This value is a constant and can be used wherever a
constant of that type is valid. For example:

void *ptr;
/* ... */
ptr = &&foo;

To use these values, you need to be able to jump to one. This is
done with the computed goto statement(1), `goto *EXP;'. For example,

goto *ptr;

Any expression of type `void *' is allowed.

One way of using these constants is in initializing a static array
that will serve as a jump table:

static void *array[] = { &&foo, &&bar, &&hack };

Then you can select a label with indexing, like this:

goto *array[i];


Jan 4 '08 #5
Frank wrote:
Before I start, please let's not discuss whether goto is evil or not.
For generated code, this can make perfect sense.

It would be interesting to know a trick how to get C to do a goto to
an address that has been assigned to a variable, i.e.
It would also be interesting to know what you are really trying to
achieve. We might be better able to suggest a solution which doesn't
abuse the language.

[snip]
I tried to pack the positions into a switch statement and made
'address_x' a variable of type 'enum',
[snip]
>
But when I look at the assembler code, it is not as efficient as a
jump to an address assigned to a variable.
So you don't just want a trick, you want to apply some measure to it to
determine if it's "efficient" enough for you?

Perhaps I won't give my solution based on an array of jmpbufs and
longjmp(), then...
>
Is there any way to get arround that?
Use a different language?

Consider using subroutine calls rather than branches? The language
supports function pointers, but not label pointers (apart from
non-standard extensions such as that used by GCC).
Jan 4 '08 #6
On Jan 4, 12:49 am, Frank <fsch...@googlemail.comwrote:
Before I start, please let's not discuss whether goto is evil or not.
For generated code, this can make perfect sense.

It would be interesting to know a trick how to get C to do a goto to
an address that has been assigned to a variable, i.e.

MyLabel:
...
address_x = MyLabel;
...
goto address_x;

I tried to pack the positions into a switch statement and made
'address_x' a variable of type 'enum', such as

enum { Label1, Label2, Label3, ... } address_x;

GotoStartPoint:
switch( address_x ) {
case Label1: ...
case Label2: ...
case Label3: ...}

...
address_x = Label2;
goto GotoStartPoint;

But when I look at the assembler code, it is not as efficient as a
jump to an address assigned to a variable.

Is there any way to get arround that?
<snip>

Perhaps you're looking for something like this:

#include <stdio.h>
#include <stdlib.h>

typedef void (*func_t)(void);
typedef func_t (*next_t)(void);

func_t foo(void);
func_t bar(void);

func_t foo(void)
{
printf("foo()\n");
return (func_t) bar;
}

func_t bar(void)
{
printf("bar()\n");
return (func_t) foo;
}

int main(void)
{
next_t f = foo;
while(1)
f = (next_t) f();

/* Never reached */
return 0;
}

Note that func_t is used as a generic function pointer type. In an
ideal world, you could use void *, but that wouldn't be strictly
conforming due to reasons I won't go into.

Typically you'll get fairly tight assembly out of this kind of thing,
but always do timing measurements on your platforms of interest. It's
really the only way to be sure, and sometimes the results are quite
surprising.

Mark F. Haigh
mf*****@sbcglobal.net

Jan 4 '08 #7
In article
<a2**********************************@e6g2000prf.g ooglegroups.com>,
Frank <fs*****@googlemail.comwrites
>Before I start, please let's not discuss whether goto is evil or not.
For generated code, this can make perfect sense.

It would be interesting to know a trick how to get C to do a goto to
an address that has been assigned to a variable, i.e.

MyLabel:
...
address_x = MyLabel;
...
goto address_x;
Yes it is quite easy BUT in the compilers where it is easy it is
completely compiler specific.

AFAIK there is no standard why of doing this elegantly
--
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\
\/\/\/\/\ Chris Hills Staffs England /\/\/\/\/
/\/\/ ch***@phaedsys.org www.phaedsys.org \/\/\
\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/

Jan 4 '08 #8
Frank said:
Before I start, please let's not discuss whether goto is evil or not.
For generated code, this can make perfect sense.

It would be interesting to know a trick how to get C to do a goto to
an address that has been assigned to a variable
Make the variable a function pointer, and assign it the address of a
function. Then just call the function through the pointer. It's more of a
gosub than a goto, but you'll end up with a better design, so that's all
to the good.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Jan 4 '08 #9
In article <a2**********************************@e6g2000prf.g ooglegroups.com>,
Frank <fs*****@googlemail.comwrote:
>Before I start, please let's not discuss whether goto is evil or not.
For generated code, this can make perfect sense.

It would be interesting to know a trick how to get C to do a goto to
an address that has been assigned to a variable, i.e.

MyLabel:
...
address_x = MyLabel;
...
goto address_x;
I tried to pack the positions into a switch statement and made
'address_x' a variable of type 'enum', such as

enum { Label1, Label2, Label3, ... } address_x;

GotoStartPoint:
switch( address_x ) {
case Label1: ...
case Label2: ...
case Label3: ...
}
...
address_x = Label2;
goto GotoStartPoint;

But when I look at the assembler code, it is not as efficient as a
jump to an address assigned to a variable.

Is there any way to get arround that?
We used to edit the assembler code :-)

I assume you have ensured (by profiling) that this really is the
bottle-neck in your code.

Some compilers (notably gcc) have an extension allowing you to assign
labels to variables. Depending on your portability constraints, this
may well be the best solution.

You could use function addresses instead of course, but presumably you
would be concerned about the call overhead, and access to shared
variables.

You maybe able to make the switch more efficient by using an unsigned
char variable and providing code for all 256[*] cases, so that the
switch code doesn't have to do range checking.
[*] Why yes, I *am* assuming 8-bit bytes.

-- Richard
--
:wq
Jan 4 '08 #10
Mark Bluemel wrote:
Frank wrote:
>Before I start, please let's not discuss whether goto is evil or
not. For generated code, this can make perfect sense.

It would be interesting to know a trick how to get C to do a goto to
an address that has been assigned to a variable, i.e.

It would also be interesting to know what you are really trying to
achieve. We might be better able to suggest a solution which doesn't
abuse the language.
>Is there any way to get arround that?

Use a different language?
It's possible the OP is doing just that as he mentioned generated code. In
that case it doesn't matter so much that the result may be inelegant
and might difficult to maintain.

I was looking at something similar myself: given labels A,B,C,D,... to
arbitrarily jump say to label B then D then A then perhaps B again according
to a table of input data, without the overheads of a function call and
ideally without even the overhead of loop control.

Apparently one answer then is to use GCC.

Bart

Jan 4 '08 #11
Hello,

Mark McIntyre <ma**********@spamcop.netschrieb:
What are you /actually/ trying to achieve ? The snipped code looks like
an attempt to solve some problem or other which you haven't explained.
Perhaps, he wants to write something like "protothreads"
(http://www.sics.se/~adam/pt/about.html)? Unfortunately, that
implementation also uses either a switch(), or the GCC extension, if
availble, to implement this.

Regards,
Spiro.

--
Spiro R. Trikaliotis http://opencbm.sf.net/
http://www.trikaliotis.net/ http://www.viceteam.org/
Jan 4 '08 #12
Frank wrote:
Before I start, please let's not discuss whether goto is evil or not.
For generated code, this can make perfect sense.
In such cases, what is the problem with
void foo(void)
{
L1: stmt1;
L2: stmt2;
L3: stmt3;
L4: stmt4;
L5: stmt5;
L6: stmt6;

goto ...;

}

???

When generating code, I see no need for label "address". So, you need to
explain why this is relevant.
--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>
Jan 5 '08 #13
Ravishankar S wrote:
>
GNU C has the extension of label variables and allows you to jump to any
such evaluated address.
So? OP could even generate this code:

....

static char jmp[7] =
"\xbd\x00\x00\x00\x00" /* movl $0,%ebp */
"\xff\xe5"; /* jmp *%ebp */
....

memcpy( jmp_table[NR], jmp, 7);

....

((int (*)) jmp_table[NR])();

--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>
Jan 5 '08 #14
In article <kb*********************@telenor.com>,
Tor Rustad <se*****@dev.null.invalidwrote:
>GNU C has the extension of label variables and allows you to jump to any
such evaluated address.
>So? OP could even generate this code:
[machine code deleted]

That would be a far less portable solution.

-- Richard
--
:wq
Jan 5 '08 #15
Richard Tobin wrote:
In article <kb*********************@telenor.com>,
Tor Rustad <se*****@dev.null.invalidwrote:
[...]
>So? OP could even generate this code:
[machine code deleted]

That would be a far less portable solution.
Regulars, rarely compare UB solutions.

--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>
Jan 5 '08 #16

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
by: Mike Hofer | last post by:
While I'd toyed with C, C++, and Java over the last 20 years or so, my principal language has been BASIC, QBASIC, then Visual Basic, and finally Visual Basic .NET. But lately, I've been using C#...
20
by: DraguVaso | last post by:
Hi, As a former VB-programmer I'm used to the "on error goto"-errorhandling. I see that in actually all the VB.NET-samples I can fin people use the "Try - catch"-errorhandling. Which of the...
77
by: M.B | last post by:
Guys, Need some of your opinion on an oft beaten track We have an option of using "goto" in C language, but most testbooks (even K&R) advice against use of it. My personal experience was that...
0
by: DR | last post by:
when i build someone's project, and right click a function "goto definition" is disabled. how to reconfigure a .net project to support "goto definition" when i right click on function calls?
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: ryjfgjl | last post by:
In our work, we often need to import Excel data into databases (such as MySQL, SQL Server, Oracle) for data analysis and processing. Usually, we use database tools like Navicat or the Excel import...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.