Labels and pointers

  • Thread starter Jean-Guillaume Pyraksos
  • Start date
J

Jean-Guillaume Pyraksos

Is a label something like a pointer i can store in a variable ?

#include <stdio.h>

void foo(void *p)
{
printf("foo\n");
goto *p;
}

int main()
{
foo(&&L1); // ???????? Explain...
printf("bar\n"); // should not be executed ?
L1:
printf("quit\n");
return 0;
}

Can somebody elaborate on this code i found on the net ?...
gcc compiles it but the result is strange (MacIntel Leopard, gcc 4.0.0)

$ gcc prog.c -o prog
$ ./prog
foo
r is not present to run this program
bar
quit
$

Thanks,

-JG
 
M

Mark Bluemel

Jean-Guillaume Pyraksos said:
Is a label something like a pointer i can store in a variable ?

#include <stdio.h>

void foo(void *p)
{
printf("foo\n");
goto *p;
}

int main()
{
foo(&&L1); // ???????? Explain...
printf("bar\n"); // should not be executed ?
L1:
printf("quit\n");
return 0;
}

Can somebody elaborate on this code i found on the net ?...

It appears to use GCC specific extensions - try building it with the
options "-ansi -Wall -pedantic"
gcc compiles it but the result is strange (MacIntel Leopard, gcc 4.0.0)

$ gcc prog.c -o prog
$ ./prog
foo
r is not present to run this program
bar
quit

The reference manual page I found
(http://gcc.gnu.org/onlinedocs/gcc/Labels-as-Values.html) says "You may
not use this mechanism to jump to code in a different function. If you
do that, totally unpredictable things will happen. The best way to avoid
this is to store the label address only in automatic variables and never
pass it as an argument."

So the code you quote is a) non-standard and b) broken even when && is
supported.
 
E

Eric Sosman

Jean-Guillaume Pyraksos said:
Is a label something like a pointer i can store in a variable ?

No. The only thing you can do with a label is `goto'
it (or for a case label, `switch' to it).
Can somebody elaborate on this code [snipped] i found on the net ?...
gcc compiles it but the result is strange (MacIntel Leopard, gcc 4.0.0)

Unless you tell it to do otherwise, the language gcc
compiles is "C with extras" rather than "C". One of those
extras is "labels as values," which allows the program to
extract a value from a label, store the value in a variable,
and `goto' the variable's value.

There are at least two reasons not to use this feature:

1) It's not C, so if you write a program that employs it
you will have difficulty getting the program to work
with compilers other than gcc.

2) If "`goto' [is] considered harmful," `goto with gadgets'
is even more so. When debugging a goto-laden program,
the question that always arises is "How in the world
did I get *here*?" With ordinary "static" gotos a text
editor can search for all mentions of the label, but if
you arrived at label `fred:' via `goto *george;' the task
is noticeably harder.

For more information on "labels as values," consult the
gcc documentation. That's the only thing that can explain
the behavior of your program; as I mentioned, it's not C.
 
K

Kenny McCormack

Eric Sosman said:
For more information on "labels as values," consult the
gcc documentation. That's the only thing that can explain
the behavior of your program; as I mentioned, it's not C.

In much the same way as "cake with frosting" isn't "cake".

I.e., only in the crazed imaginations of CLC regulars.
 
M

Martin Ambuhl

Jean-Guillaume Pyraksos said:
Is a label something like a pointer i can store in a variable ?

Not in the standard language. The code you posted uses a gcc extension
(perhaps available on some other implementations) and is properly
addressed in a gnu-specific newsgroup specific to gcc (or those other
implementations). It cannot be used in programs intended to be portable.
#include <stdio.h>

void foo(void *p)
{
printf("foo\n");
goto *p;
}

int main()
{
foo(&&L1); // ???????? Explain...
This is explained in the gcc documentation.
Always check the documentation for your
implementation (along with the C FAQ) before posting.
printf("bar\n"); // should not be executed ?
L1:
printf("quit\n");
return 0;
}

gcc invoked as a compiler for standard C should produce diagnostics like
a.c: In function 'foo':
a.c:6: warning: ISO C forbids 'goto *expr;'
a.c: In function 'main':
a.c:11: warning: taking the address of a label is non-standard
where line 6 is the 'goto *p;'m and line 11 is 'foo(&&L1);'

But even when gcc compiles its default non-standard language, called
GNU-C, the above code is malformed. The gcc documentation contains the
language "You may not use this mechanism to jump to code in a different
function. If you do that, totally unpredictable things will happen. The
best way to avoid this is to store the label address only in automatic
variables and never pass it as an argument."

So the code is
a) complete gibberish as far as the standard C language is concerned
b) incorrect even in the non-standard GNU-C language since it attempts
"to jump to code in a different function", and violates the suggestion
that one "never pass it as an argument."
Can somebody elaborate on this code i found on the net ?...
gcc compiles it but the result is strange (MacIntel Leopard, gcc 4.0.0)

$ gcc prog.c -o prog
$ ./prog
foo
r is not present to run this program
bar
quit
$

The output you see is one of the "totally unpredictable things" the gcc
documentation warns about.
 
R

Richard Tobin

Jean-Guillaume Pyraksos said:
Is a label something like a pointer i can store in a variable ?

As others have pointed out, only when using an extension like the
one that gcc provides.
void foo(void *p)
{
printf("foo\n");
goto *p;
}

int main()
{
foo(&&L1); // ???????? Explain...
printf("bar\n"); // should not be executed ?
L1:
printf("quit\n");
return 0;
}
Can somebody elaborate on this code i found on the net ?...

Again, as others have pointed out, this code is using the gcc
extension wrongly. You should only use it for jumps where a
normal jump to the location would be legal.
gcc compiles it but the result is strange (MacIntel Leopard, gcc 4.0.0)

$ gcc prog.c -o prog
$ ./prog
foo
r is not present to run this program
bar
quit

My guess would be that the goto is "working", but because the function
foo is still active the format string "quit" is not in the right place
relative to the stack pointer, and instead it gets the end of some
other string (you can find what it probably is by googling for "is not
present to run this program"). It then executes main's return, but
because foo's stack frame is still there it returns to main, and
continues executing normally.

-- Richard
 
R

Richard Tobin

Eric Sosman said:
There are at least two reasons not to use this feature:

And there are also reasons to use it, though most people probably
won't encounter them. It seems quite in accord with the spirit of
C: no worse, for example, than setjmp()/longjmp().

-- Richard
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,768
Messages
2,569,574
Members
45,048
Latest member
verona

Latest Threads

Top