Code zu schnell?



  • Wie kann folgendes möglich sein:

    MyClass::MyClass()
    {
        std::cout << "--> MyClass::MyClass()" << std::endl;
    
        // some long operations
    
        std::cout << "<-- MyClass::MyClass()" << std::endl;
    }
    
    void MyClass::func()
    {
        std::cout << "--> MyClass::func()" << std::endl;
    
        // foooooo
    
        std::cout << "<-- MyClass::func()" << std::endl;
    }
    
    .
    .
    .
    
    int main()
    {
        MyClass* cl( new MyClass() );
    
        cl->func();
    }
    
    // Ausgabe:
    --> MyClass::MyClass()
    --> MyClass::func()
    ...
    <-- MyClass::MyClass()
    

    kurz: warum wird die Methode aufgerufen, bevor der Konstruktor fertig ist? Oder leide ich an Hirngespinsten?



  • Also ich bekomme folgende Ausgabe:

    --> MyClass::MyClass()
    <-- MyClass::MyClass()
    --> MyClass::func()
    <-- MyClass::func()
    

    Entspricht doch dem was du erwartest oder nicht?
    Zuerst der Ctor, dann die Funktion.

    EDIT:Wenn man davon ausgeht, es läuft wirklich so ab wie oben aufgezeigt.



  • func() wird anscheinend vom Konstruktor aufgerufen. Im 'some long operatins' Block.



  • zwutz schrieb:

    Wie kann folgendes möglich sein:

    An sich sollte sowas nicht möglich sein, aber ich habe bereits auf alten Compilern ähnliche Probleme (in Kombination mit sehr schlechter Optimierung) gehabt. Dies lies sich auch nur dadurch lösen das man die Optimierungen teilweise deaktiviert hat.

    Ansonsten kann ich mir sowas nur vorstellen wenn es sich um Multithreading und Unterschiedliche Instanzen handelt (Gib doch mal den this-Zeiger zusätzlich aus, um festzustellen ob es wirklich das gleiche Objekt ist).

    cu André



  • connan schrieb:

    func() wird anscheinend vom Konstruktor aufgerufen. Im 'some long operatins' Block.

    nein, wird es nicht...

    aber ich hab hier schon einige konfuse Vorkommnisse gehabt, die ich mir nicht erklären konnte und deren Lösung sich jeder Logik entbehrt.... was genau das Proble mist, kann ich also nicht sagen... vielleicht hat der Compiler zu beherzt optimiert oder die Mondphase war ungünstig 🙂

    Anderer Fall, den wir bei uns hatten:
    In einer init()-Methode, die vom Konstruktor aufgerufen wurde, wurde eine Combobox gefüllt. Kurz darauf wurde der Wert dieser Box ausgelesen und in einem SQL-String eingebaut. Funktioniert wunderbar, bis uns einige Kollegen einen SQL-Fehler gemeldet hatten, der darauf schließen lässt, dass die Combobox eben noch nicht befüllt war (war sie aber laut den Screenshots).
    Die Lösung: Es wurde ein neuer Link auf die Binary angelegt, über den die Anwendung gestartet wird. An der Anwendung selbst wurde nichts verändert und trotzdem ist das Problem seitdem nichtmehr aufgetreten.

    Oberes Beispiel ist ähnlich.
    Ich selbst hatte auch schon das Problem, dass Ausgaben nicht in der Reihenfolge gemacht wurden, in der ich sie im Code hatte. Hab das aber auf ein Problem meiner IDE geschoben, die evtl was falsch auffängt. Bei einem Kollegen führte obiges aber zu einem Absturz, da der Pointer ungültig war (obwohl er es nicht sein dürfte).
    Evtl liegts auch daran, dass sich hinter "some long operations" auch diverse Dateizugriffe verbergen, die etwas dauern können

    -edit- und ja, wir haben einige nicht sehr moderne Compiler am laufen (gcc 3.4.2)
    hat mich schon viel Ärger gekostet -.-



  • zwutz schrieb:

    connan schrieb:

    func() wird anscheinend vom Konstruktor aufgerufen. Im 'some long operatins' Block.

    nein, wird es nicht...

    Dann bleiben eigentlich nur wenige Möglichkeiten:
    1. Entweder Optimiert der Compiler zu viel (Habe ich persönlich bislang nur mit wirklich alten Compilern wie den Power++ erlebt).
    2. Es handelt sich um verschiedene Objekte (z.B. durch Multithreading oder Eventhandling - zumindestens unter Windows kann manchmal in einer Singlethreaded Programm beim Eventhandling doch Multithreading auftreten...).
    3. Auch wenn man weder einen direkten noch indirekten Aufruf sieht ist doch einer im Konstruktor vorhanden (und übersehen).

    zwutz schrieb:

    Evtl liegts auch daran, dass sich hinter "some long operations" auch diverse Dateizugriffe verbergen, die etwas dauern können

    Das darf aber eigentlich nur dann zu einer verkehrten Aufrufreihenfolge führen, wenn dies asynchrone Zugriffe sind.

    cu André



  • Sieh dir doch einfach mal den generierten Assemblercode an.



  • zwutz schrieb:

    connan schrieb:

    func() wird anscheinend vom Konstruktor aufgerufen. Im 'some long operatins' Block.

    nein, wird es nicht...

    aber ich hab hier schon einige konfuse Vorkommnisse gehabt, die ich mir nicht erklären konnte und deren Lösung sich jeder Logik entbehrt.... was genau das Proble mist, kann ich also nicht sagen... vielleicht hat der Compiler zu beherzt optimiert oder die Mondphase war ungünstig 🙂

    Anderer Fall, den wir bei uns hatten:
    In einer init()-Methode, die vom Konstruktor aufgerufen wurde, wurde eine Combobox gefüllt. Kurz darauf wurde der Wert dieser Box ausgelesen und in einem SQL-String eingebaut. Funktioniert wunderbar, bis uns einige Kollegen einen SQL-Fehler gemeldet hatten, der darauf schließen lässt, dass die Combobox eben noch nicht befüllt war (war sie aber laut den Screenshots).
    Die Lösung: Es wurde ein neuer Link auf die Binary angelegt, über den die Anwendung gestartet wird. An der Anwendung selbst wurde nichts verändert und trotzdem ist das Problem seitdem nichtmehr aufgetreten.

    Oberes Beispiel ist ähnlich.
    Ich selbst hatte auch schon das Problem, dass Ausgaben nicht in der Reihenfolge gemacht wurden, in der ich sie im Code hatte. Hab das aber auf ein Problem meiner IDE geschoben, die evtl was falsch auffängt. Bei einem Kollegen führte obiges aber zu einem Absturz, da der Pointer ungültig war (obwohl er es nicht sein dürfte).
    Evtl liegts auch daran, dass sich hinter "some long operations" auch diverse Dateizugriffe verbergen, die etwas dauern können

    -edit- und ja, wir haben einige nicht sehr moderne Compiler am laufen (gcc 3.4.2)
    hat mich schon viel Ärger gekostet -.-

    Vermutlich liegen all eure Probleme (oder zumindest die meisten) daran dass entweder
    a) das Programm voll mit grausamen Fehlern ist (fremden Speicher überschreiben, fehlende Synchronisation etc.) oder
    b) eure Hardware total im Eimer ist oder
    c) beides

    Ich tippe auf (a). Ist ein Erfahrungswert.

    Dass im ctor Dateizugriffe gemacht werden kann nicht das Problem sein -- du kannst im Prinzip das ganze Programm im ctor irgendeiner Klasse laufen lassen ohne dass irgendwelche Probleme auftreten.



  • Bin ebenfalls für a)


Anmelden zum Antworten