FighterFigger Geschrieben 25. Mai 2004 Geschrieben 25. Mai 2004 Hallo Mädels und Jungx, ich möchte gerne über einen Enum iterieren, befinde mich aber in einem Zeit-kritischen Bereich (ca. 5 Mio. Aufrufe dieses Blocks) In C++ sieht das bei mir so aus: // - enum ---------------------------------------------- namespace defs {enum months {JANUARY, FEBRUARY, ... DECEMBER, LAST_MONTH};} // - enum ---------------------------------------------- ... // - block ---------------------------------------------- for (int month = defs::JANUARY; month < defs::LAST_MONTH; month++) {function(defs::months(month)); // <---- function nimmt ein Element des Enums} // - block ---------------------------------------------- Ich weiß, daß ich optimieren könte, wenn ich von vornherein mit Integern plane, ich möchte die Enums gerne der Übersicht wegen weiterhin nutzten. Fragen: 1. Weiß jemand, wie Aufwendig der Operator (oder Konstruktor) ist, der einen Integer in ein Enum-Element zurück wandelt? 2. Wird dieser Operator vielleicht sogar durch MS-C++-Compiler wegoptimiert? Denn selbst, wenn ich den ++Operator für das Enum definiere scheine ich um diesen Operator (oder ist das ein Konstruktor) nicht umher zu kommen. Zitieren
nic_power Geschrieben 25. Mai 2004 Geschrieben 25. Mai 2004 Hallo, enumerationen werden intern als Integers behandelt. In Deinem Beispiel erhält "JANUARY" den Wert 0, "FEBRUARY" den Wert 1 usw. usf. Ein Umwandeln der symbolischen Namen ist also nicht notwendig. Nic Zitieren
FighterFigger Geschrieben 25. Mai 2004 Autor Geschrieben 25. Mai 2004 Danke für die Antwort, aber bis zur Iteration ist noch alles klar. Ekelig hingegen wird es dann bei der Funktion function. void function(defs::months myMonth); Diese Funktion nimmt einen Wert des Types defs::months und bei C++ reicht da ein Integer nicht aus, ich muß diesen erst konvertieren mit defs::months(int i) Und diese Konversion ... wie lange dauert diese, und wird sie durch Compiler optimiert oder nicht? Gruß - ich :e@sy Zitieren
nic_power Geschrieben 25. Mai 2004 Geschrieben 25. Mai 2004 Hallo, Diese Funktion nimmt einen Wert des Types defs::months und bei C++ reicht da ein Integer nicht aus. Doch, da reicht ein Integer völlig aus. Enums werden intern als Integers behandelt. D.h. auch bei der Übergabe an Funktionen wird ein Integer übergeben (nicht etwa JANUARY oder FEBRUARY als String, es findet daher auch keine Konvertierung statt). Jeder halbwegs brauchbare Compiler wird Optimierungen vornehmen, so dass der Integer in einem Register an die Funktion übergeben wird. Ein guter Compiler generiert Code bei dem es kein Unterschied macht, ob Du ein Parameter an die Funktion übergibst oder nicht, da sich der Parameter beim Aufruf bereits im entsprechenden Register befindet (das ist unter Umständen auch abhängig von der Prozessorarchitektur auf der Du arbeitest). Probiere mal folgendes aus: #include <iostream.h> namespace defs { enum months { JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER, LAST_MONTH }; } void function(defs::months myMonth) { cout << myMonth << endl; } int main() { for (int month = defs::JANUARY; month < defs::LAST_MONTH; month++) function(defs::months(month)); } [/php] Nic Zitieren
FighterFigger Geschrieben 25. Mai 2004 Autor Geschrieben 25. Mai 2004 Hallo nic_power, In der folgenden Codezeile deines Codes rufst du auch diesen Konstruktor (oder ist es ein Operator) auf, da eben in C++ nicht einfach nur ein Integer übergeben werden kann. Dieser Konstruktor (oder ist es ein Operator?) heißt so, wie der Enum-Typ function(defs::months(month)); Das Problem ist ja, daß ein Enum mehrere Einträge mit identischem Wert haben kann. Also hat zwar jeder EnumWert genau einen Integer zugewiesen, aber ein Integer kann einen, keinen oder mehrere Enumtypen zugeordnet haben. Sucht mein Programm immer nach dem Enum, mit der entsprechenden Zahl, oder akzeptiert er die Zahl, wie sie ist ... Also sehe ich das richtig ... in der Laufzeit existiert diese Konversion gar nicht mehr, sondern die ist nur für den Compiler - so wie ein cast? Gruß - ich Zitieren
Guybrush Threepwood Geschrieben 25. Mai 2004 Geschrieben 25. Mai 2004 In der folgenden Codezeile deines Codes rufst du auch diesen Konstruktor (oder ist es ein Operator) auf, da eben in C++ nicht einfach nur ein Integer übergeben werden kann. Ich verstehe nicht was du damit meinst das nicht einfach nur ein Integer übergeben werden kann. Es wird der Funktion function nur ein Integer übergeben, da sich hinter den einzelnen Elementen des Enums nichts anderes verbirgt. Man könnte es fast mit einem #define vergleichen, nur das ein definierter Wert vom Präprozessor ausgetauscht wird und das Enum, so weit ich weiß, wie eine normale Variable behandelt wird. Zitieren
nic_power Geschrieben 25. Mai 2004 Geschrieben 25. Mai 2004 Hallo, Das Problem ist ja, daß ein Enum mehrere Einträge mit identischem Wert haben kann. Also hat zwar jeder EnumWert genau einen Integer zugewiesen, aber ein Integer kann einen, keinen oder mehrere Enumtypen zugeordnet haben. Wo hast Du denn diese Information her? Die Namen der Enumeratoren innerhalb eines Scopes müssen unterschiedlich sein. Dabei könnern innerhalb einer Enumeration durchaus identische Werte verwendet werden. Der Wert muss jedoch immer entweder ein integer sein, oder ein Wert welcher entsprechend konvertiert werden kann ("integral promotion", dies ist jedoch keine echte Konvertierung, der Datentyp wird vielmehr auf ein Integer "erweitert"); dazu gehören char, short int usw. Das kannst Du überprüfen, indem Du die Zeile "SEPTEMBER" in "SEPTEMBER=30" änderst und das Programm dann nochmals laufen läßt. Nic Zitieren
FighterFigger Geschrieben 25. Mai 2004 Autor Geschrieben 25. Mai 2004 Ich verstehe nicht was du damit meinst das nicht einfach nur ein Integer übergeben werden kann. Es wird der Funktion function nur ein Integer übergeben, da sich hinter den einzelnen Elementen des Enums nichts anderes verbirgt. Hi Guybrush, ich meine damit, daß folgendes nicht funktioniert: function(10); und auch nicht: int monat = 10; function(monat);[/PHP] beides führt zu fehlern. Es geht erst wenn: [PHP]function(defs:months(10)); oder: int monat = 10; function(daef::months(monat));[/PHP] Also kann ich nur kompilieren, wenn ich [i]defs::months(...)[/i] hinzufüge. Beeinflußt dieser Zusatz nun also die Laufzeit oder ist das nur für den Compiler? und [b]nic_power[/b]: ich meinte sowas: [PHP]enum zahlen { EINS = 1, ZWEI, ZWO = ZWEI, DREI = 3, VIER, VIELE = 10 }; in diesem Enum ist die 2 zweimal vertreten, für 5 bis 9 gibt es aber keinen Enum. (also jeder Wert nur max einmal, aber Integer können öfter oder sogar gar nicht auftreten) Wie handelt der während der Laufzeit folgende Aufrufe: zahlen(2); // Aufruf 1 zahlen(6); // Aufruf 2[/PHP] Zitieren
Klotzkopp Geschrieben 26. Mai 2004 Geschrieben 26. Mai 2004 Die symbolischen Konstanten des enums sind nur zur Compilezeit bekannt. Durch den Cast von int nach months beim Aufruf von function hebelst du die Compilezeit-prüfung aus. Eine Laufzeitprüfung findet grundsätzlich nicht statt. Zitieren
FighterFigger Geschrieben 26. Mai 2004 Autor Geschrieben 26. Mai 2004 ... beim Aufruf von function hebelst du die Compilezeit-prüfung aus. Eine Laufzeitprüfung findet grundsätzlich nicht statt. Hurra - das ist, was ich wissen wollte Also ist's kein Konstruktor und kein Konvertierungs-Operator sondern ein Cast. Danke an alle beteiligten :beagolisc Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.