operator new



  • @Bashar: Die entsprechende Stelle in C++03 ist 27.3 und enthält den Passus in der Form nicht. Ich vermute, dass MSVC 2010 diesen Teil von C++11 schlicht noch nicht implementiert.

    Wenn ich das alles richtig lese, sollte sich das Problem aber durch das Einfügen von

    namespace {
      std::ios_base::Init const make_sure_cout_and_stuff_exists;
    }
    

    an geeigneter Stelle beheben lassen, oder? Denkbar auch eine funktionslokale statische Konstante, aber wenn der operator new dann nicht benutzt wird, bevor Threads gestartet werden, hat man unter Umständen ein data race.



  • seldon schrieb:

    @Bashar: Die entsprechende Stelle in C++03 ist 27.3 und enthält den Passus in der Form nicht.

    Aus C++98:

    The objects are constructed, and the associations are established at some time prior to or during first time an object of class basic_ios<charT, traints>::Init is constructed, and in any case before the body of main begins execution. The objects are not destroyed during program execution.

    Also ist der Unterschied wohl, dass Einbinden von <iostream> kein Init-Objekt erzeugen muss.

    Ich vermute, dass MSVC 2010 diesen Teil von C++11 schlicht noch nicht implementiert.

    Naja, was im Standard steht und was die Realität ist muss nicht übereinstimmen, Abweichungen kann es dabei in beide Richtungen geben. Manche Sachen sind Konsens und funktionieren in allen Implementierungen, stehen aber nicht so im Standard. Ein Beispiel dafür ist das berüchtigte Hello-World, das nur <iostream> einbindet, während laut Standard noch <ostream> benötigt wird.

    Man hat sich bei der Entwicklung der IOStream-Library sehr viele Gedanken über die Initialisierungsreihenfolge der Standard-Streams gemacht. Ich finde es schwer vorstellbar, dass das an MSVC völlig vorbeigegangen sein soll. Irgendeine Lösung werden sie dafür gefunden haben.

    MSDN schreibt z.B.:

    All the objects declared in this header share a peculiar property — you can assume they are constructed before any static objects you define, in a translation unit that includes <iostream>. Equally, you can assume that these objects are not destroyed before the destructors for any such static objects you define. (The output streams are, however, flushed during program termination.) Therefore, you can safely read from or write to the standard streams before program startup and after program termination.

    This guarantee is not universal, however. A static constructor may call a function in another translation unit. The called function cannot assume that the objects declared in this header have been constructed, given the uncertain order in which translation units participate in static construction. To use these objects in such a context, you must first construct an object of class ios_base::Init.

    Wenn ich das alles richtig lese, sollte sich das Problem aber durch das Einfügen von

    namespace {
      std::ios_base::Init const make_sure_cout_and_stuff_exists;
    }
    

    an geeigneter Stelle beheben lassen, oder?

    So lese ich das auch.



  • bluffer schrieb:

    Das ist halt typisch an C++; man weiss nie was passiert. Nimm lieber fprintf, das dürfte sicher gehen.

    Die printf Familie hat genau das gleiche Problem, nur dass sie etwa eine halbe Sekunde länger durchhält. 😉



  • seldon schrieb:

    namespace {
      std::ios_base::Init const make_sure_cout_and_stuff_exists;
    }
    

    an geeigneter Stelle beheben lassen, oder?

    Ändern tut es leider nichts. 😞



  • Wie sieht denn dein Code aus?



  • Michael E. schrieb:

    Wie sieht denn dein Code aus?

    Äh.. so?
    http://ideone.com/YYXn6

    .. (Und ja, es fehlt nothrow und ich habe zu viele Autos. ;))



  • Den Fehler kann ich mit VS 2010 Release Build nicht reproduzieren.



  • Michael E. schrieb:

    Den Fehler kann ich mit VS 2010 Release Build nicht reproduzieren.

    Interessant. Ich habe das mal bei einem anderen Projekt getestet, und da lief es sofort. Habe also mit den Einstellungen rumgespielt, und ich denke den Fehler gefunden zu haben. Teste mal mit /MT statt /MD.



  • Jo, dann krachts bei mir auch.



  • Michael E. schrieb:

    Jo, dann krachts bei mir auch.

    Gut. Also wenn das tatsächlich standardkonform sein sollte, halte ich das für einen ziemlich üblen Bug. Weiß jemand ob das schon bekannt ist oder so?


Anmelden zum Antworten