|
|
|
#1 |
|
Messages: n/a
Hébergeur: |
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 |
|
|
|
#2 |
|
Messages: n/a
Hébergeur: |
Jean-Guillaume Pyraksos wrote:
> 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. |
|
|
|
#3 |
|
Messages: n/a
Hébergeur: |
Jean-Guillaume Pyraksos wrote:
> 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. -- Eric Sosman esosman@ieee-dot-org.invalid |
|
|
|
#4 |
|
Messages: n/a
Hébergeur: |
In article <8_CdnYE_bdT0b9vanZ2dnUVZ_qmlnZ2d@comcast.com>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote: .... > 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. |
|
|
|
#5 |
|
Messages: n/a
Hébergeur: |
Jean-Guillaume Pyraksos wrote:
> 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. |
|
|
|
#6 |
|
Messages: n/a
Hébergeur: |
Kenny McCormack wrote:
> In article <8_CdnYE_bdT0b9vanZ2dnUVZ_qmlnZ2d@comcast.com>, > Eric Sosman <esosman@ieee-dot-org.invalid> wrote: > ... >> 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". You misspelled "engine oil". > I.e., only in the crazed imaginations of CLC regulars. And "prized". -- And Teh Hedgehog "Never ask that question!" Ambassador Kosh, /Babylon 5/ |
|
|
|
#7 |
|
Messages: n/a
Hébergeur: |
In article <wissme-B21192.16130923112007@malibu.unice.fr>,
Jean-Guillaume Pyraksos <wissme@hotmail.com> wrote: >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 -- "Consideration shall be given to the need for as many as 32 characters in some alphabets" - X3.4, 1963. |
|
|
|
#8 |
|
Messages: n/a
Hébergeur: |
In article <8_CdnYE_bdT0b9vanZ2dnUVZ_qmlnZ2d@comcast.com>,
Eric Sosman <esosman@ieee-dot-org.invalid> wrote: > 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 -- "Consideration shall be given to the need for as many as 32 characters in some alphabets" - X3.4, 1963. |
|
![]() |
| Outils de la discussion | |
|
|