Warum goto manchmal doch ganz nützlich ist ^^
Verfasst: Fr Apr 12, 2013 1:11 pm
Genesys kann goto. Dafür gibt es einen Grund: Ich habe zwar keine Ahnung, wo man es brauchen müsste, aber ich weiß auch nicht alles und wenn jemand anderer zu dem Punkt kommt, dass er es braucht, wäre es doch gut, wenn es goto auch gibt.
Ich generiere derzeit C++-Quellcodes, ganz einfach, weil es schneller geht, ihn zu generieren, als ihn zu schreiben. Es geht also um viel Code, die erzeugte Headerdatei hat rund 1.8MB, die Cpp-Datei nochmal 435KB.
Eine Factory-Methode erhält dabei einen String und muss dafür eine von rund 650 Klassen erzeugen. Das folgende ist geschwindigkeitstechnisch nicht ideal, aber es wird sehr viel Code generiert und das erste Ziel ist, etwas zu erreichen, was funktioniert. Folgendes wird generiert:
Das ganze etwa 650 Mal.
Ergebnis: Compiler Error C1061: compiler limit : blocks nested too deeply.
Visual Studio erlaubt "nur" 128 Verschachtelungen. Erster Gedanke:
Müsste funktionieren, aber eine Schleife, um nachfolgende Abfragen zu verhindern?
Möglichkeit 2:
Eine Funktion, die was immer xxx::Create sofort mit return zurückspielt. Quasi eine zweite Factory-Funktion, die von der ersten Factory-Funktion aufgerufen wird, die dann die Nachbearbeitung macht.
Möglichkeit 3:
Jetzt kompiliert es - nur streikt VC2010, weil ihm das Objektfile zu groß ist. Die Fehlermeldung liefert freundlicherweise aber gleich die Lösung: den Compilerswitch: "/bigobj". Es läuft zumindest 
Goto erschien mir hier die sinnvollste Lösung. Oder gibt es schönere Vorschläge?
Ich generiere derzeit C++-Quellcodes, ganz einfach, weil es schneller geht, ihn zu generieren, als ihn zu schreiben. Es geht also um viel Code, die erzeugte Headerdatei hat rund 1.8MB, die Cpp-Datei nochmal 435KB.
Eine Factory-Methode erhält dabei einen String und muss dafür eine von rund 650 Klassen erzeugen. Das folgende ist geschwindigkeitstechnisch nicht ideal, aber es wird sehr viel Code generiert und das erste Ziel ist, etwas zu erreichen, was funktioniert. Folgendes wird generiert:
Code: Alles auswählen
if( false );
else if( classname == Snafu::ClassName ) result = Snafu::Create( file );
else if( classname == Foo::ClassName ) result = Foo::Create( file );
else if( classname == Bar::ClassName ) result = Bar::Create( file );
...
Ergebnis: Compiler Error C1061: compiler limit : blocks nested too deeply.
Visual Studio erlaubt "nur" 128 Verschachtelungen. Erster Gedanke:
Code: Alles auswählen
while( true )
{
if( classname == Snafu::ClassName ) { result = Snafu::Create( file ); break; }
if( classname == Foo::ClassName ) { result = Foo::Create( file ); break; }
if( classname == Bar::ClassName ) { result = Bar::Create( file ); break; }
...
break;
}
Möglichkeit 2:
Eine Funktion, die was immer xxx::Create sofort mit return zurückspielt. Quasi eine zweite Factory-Funktion, die von der ersten Factory-Funktion aufgerufen wird, die dann die Nachbearbeitung macht.
Möglichkeit 3:
Code: Alles auswählen
if( classname == Snafu::ClassName ) { result = Snafu::Create( file ); goto label; }
if( classname == Foo::ClassName ) { result = Foo::Create( file ); goto label; }
if( classname == Bar::ClassName ) { result = Bar::Create( file ); goto label; }
label:

Goto erschien mir hier die sinnvollste Lösung. Oder gibt es schönere Vorschläge?