Ist es möglich, die Adresse eines Labels in einer Variablen zu speichern und mit goto zu springen?
Ich weiß, jeder hasst gotos. In meinem code, aus Gründen, die ich betrachtet haben, und bin bequem mit, Sie bieten eine effektive Lösung (dh ich bin nicht auf der Suche nach "don' T do that" als Antwort, ich verstehe Ihre Vorbehalte, und zu verstehen, warum ich mit Ihnen sowieso).
Bisher wurden Sie fantastisch, aber ich wollen, erweitern Sie die Funktionalität in einer Weise, die mich verpflichtet, im wesentlichen in der Lage sein zu speichern Zeiger auf den Etiketten, gehen Sie dann, um Sie später.
Wenn dieser code funktioniert, ist es entspräche der Art von Funktionalität, die ich brauche. Aber es funktioniert nicht, und 30 min googeln hat nicht offenbart alles. Hat jemand irgendwelche Ideen?
int main (void)
{
int i=1;
void* the_label_pointer;
the_label:
the_label_pointer = &the_label;
if( i-- )
goto *the_label_pointer;
return 0;
}
InformationsquelleAutor der Frage Joshua Cheek | 2009-11-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
C-und C++ - standards unterstützen diese Funktion nicht. Jedoch, die GNU Compiler Collection (GCC) enthält ein nicht-standard-Erweiterung für dies zu tun, wie beschrieben in dieser Artikel. Im wesentlichen, Sie haben ein special-operator "&&" , berichtet die Adresse von dem Etikett als Typ "void*". Siehe den Artikel für weitere details.
P. S. In anderen Worten, verwenden Sie einfach "&&" statt "&" in deinem Beispiel, und es wird funktionieren auf GCC.
P. P. S. ich weiß, Sie wollen nicht mich, es zu sagen, aber ich sage es trotzdem... MACH DAS NICHT!!!
InformationsquelleAutor der Antwort Michael Aaron Safyan
Sie können tun, etwas ähnliches mit setjmp/longjmp.
InformationsquelleAutor der Antwort R Samuel Klatchko
Entsprechend dem C99-standard, § 6.8.6, die syntax für eine
goto
ist:Also, auch wenn Sie vielleicht die Adresse von einem Etikett, Sie könnte nicht verwenden Sie es mit springen.
Könnten Sie kombinieren eine
goto
mit einemswitch
die wie ein berechnetgoto
für einen ähnlichen Effekt:Wenn Sie diese für alles andere als einen obfuscated C contest, ich werde Euch jagen und Euch verletzt.
InformationsquelleAutor der Antwort outis
Den
switch ... case
- Anweisung ist im wesentlichen eine berechnetgoto
. Ein gutes Beispiel dafür, wie es funktioniert, ist die bizarre hack bekannt als Duff ' s Device:Können Sie nicht
goto
aus einer beliebigen Lage, mit dieser Technik, aber Sie können wickeln Sie Ihre gesamte Funktion in eineswitch
Aussage basiert auf eine variable, dann setzen Sie die variable, die angibt, wohin Sie gehen wollen, undgoto
dass die switch-Anweisung.Natürlich, wenn Sie dies tun, eine Menge, die Sie wollen, um zu schreiben, ein paar Makros zu wickeln.
Diese Technik, zusammen mit einigen Komfort-Makros können auch verwendet werden, um zu implementieren Coroutinen in C.
InformationsquelleAutor der Antwort Brian Campbell
In der sehr, sehr, sehr alte version der C-Sprache (denken Sie an die Zeit, Dinosaurier durchstreiften die Erde), bekannt als "C Reference Manual" version (das bezieht sich auf eine Dokument geschrieben von Dennis Ritchie), Etiketten formal hatte der Typ "array von int" (seltsam, aber wahr), was bedeutet, dass Sie könnten erklären, ein
int *
variableund zuweisen der Adresse des label an, dass die variable
Später konnte man mit dieser Variablen als Operanden von
goto
AnweisungJedoch in ANSI C diese Funktion geworfen wurde. Im modernen standard-C kann man die Adresse von einem Etikett, und man kann nicht "eingestellt"
goto
. Dieses Verhalten soll simuliert werden mitswitch
Anweisungen, Zeiger auf Funktionen und andere Methoden etc. Eigentlich sogar "C Reference Manual" selbst sagte, dass "Label-Variablen sind generell eine schlechte Idee; die switch-Anweisung macht Sie fast immer überflüssig" (siehe "14.4 Etiketten").InformationsquelleAutor der Antwort AnT
Ich kenne das Gefühl dann jeder sagt, dass es nicht getan werden sollte; es ist nur hat zu tun. Hier ist, wie es zu tun:
Dem label dereferenzierungsoperator && funktioniert nur mit gcc. Und natürlich die jumpto Montage-makro implementiert werden müssen, speziell für jeden Prozessor (funktioniert mit 32-und 64-bit-x86). Beachten Sie auch, dass es keine Garantie gibt, dass der Zustand des Stacks ist das gleiche an zwei verschiedenen Punkten in der gleichen Funktion. Und zumindest mit einigen Optimierung eingeschaltet es ist möglich, dass der compiler davon einige Register enthalten einen gewissen Wert an dem Punkt, nach dem Etikett. Diese Art von Dingen kann leicht angeschraubt, dann tut verrückte Scheiße, die der compiler nicht erwarten. Werden Sie sicher, Beweis Lesen Sie das kompilierte code.
InformationsquelleAutor der Antwort Fabel
Werde ich beachten Sie, dass das funktional beschrieben hier (einschließlich && gcc) ist IDEAL für die Implementierung einer Forth-interpreter Sprache in C., Dass die Schläge alle die "nicht-machen" - Argumente aus dem Wasser - Passung, die Funktionalität und die Art und Weise Hervor, die innere interpreter arbeitet ist zu gut, um zu ignorieren.
InformationsquelleAutor der Antwort Kip Ingram
Nur offiziell unterstützt, was, die Sie tun können, mit einem Etikett in C ist
goto
. Wie Sie bemerkt haben, können Sie nicht die Adresse oder speichert ihn in einer variable oder sonst etwas. Also anstatt zu sagen "Tu das nicht", werde ich sagen, "Sie können das nicht tun".Sieht aus wie Sie haben zu finden eine andere Lösung. Vielleicht Assembler, wenn das ist performance-kritisch?
InformationsquelleAutor der Antwort Greg Hewgill
Verwenden Sie Funktionszeiger und einer while-Schleife. Machen Sie nicht ein Stück code jemand haben wird, zu bedauern, Befestigung für Sie.
Ich nehme an, Sie versuchen, ändern Sie die Adresse des label irgendwie extern. Funktionszeigern arbeiten.
InformationsquelleAutor der Antwort
Lesen: setjmp.h - Wikipedia Wie bereits gesagt, es ist möglich, mit setjmp/longjmp, mit dem Sie speichern können, ein jumppoint in eine variable und springen später wieder zurück.
InformationsquelleAutor der Antwort icefex
InformationsquelleAutor der Antwort RUE_MOHR
Laut dieser threadlabel Punkte sind kein standard, also ob Sie arbeiten oder nicht, würde davon abhängen, den compiler, den Sie verwenden.
InformationsquelleAutor der Antwort Kaleb Brasee
Können Sie zuweisen label variable mit &&.
Hier finden Sie Ihre geänderten code.
InformationsquelleAutor der Antwort Mayank
Können Sie etwas tun, wie Fortran-computer-springen mit Zeigern auf Funktionen.
InformationsquelleAutor der Antwort QuentinUK