Automatische Initialisierung einer Tabelle



  • static class Member werden vor der dynamischen Konstruktion initialisiert. Von daher ist das sicher. Was aber passiert, wenn man im Code ein static Led blueLED; hat, ist nicht definiert, weil es keine definierte Reihenfolge für die Initialisierung von statics gibt. Solange aber im Konstruktor von Led nicht auf das static zugegriffen wird, bist Du da auf der sicheren Seite.

    s. auch : http://stackoverflow.com/questions/1079623/what-is-the-lifetime-of-class-static-variables-in-c



  • OK, vielen Dank, v.a. für den stackoverflow-Artikel.

    Ich habe gerade festgestellt, dass der Constructor noch vor main( ) aufgerufen wird, und sogar, wenn überhaupt kein LED-Objekt erzeugt wird (also nur durch das #include "Led.h"). Das ist interessant.

    Solange die Tabelle nicht groß ist, sollte das kein Problem sein.

    Eine sauberere Lösung wäre demnach vermutlich ein echtes Singleton, was nur bei Bedarf "anspringt".



  • Ich würde maximal die Initialisierung (Einfügen der Werte in die map) verzögern, nicht das Anlegen der std::map selbst.
    boost::call_once ist eine gute Möglichkeit das ganze thread-safe zu machen.



  • -> construct on first use idiom

    int  getSequence( ) const 
    {
      static SeqTable seqTable; 
      return seqTable( mySequence ); 
    }
    


  • brotbernd schrieb:

    -> construct on first use idiom

    int  getSequence( ) const 
    {
      static SeqTable seqTable; 
      return seqTable( mySequence ); 
    }
    

    * Falsche Syntax
    ->

    int getSequence() const 
    {
      static SeqTable seqTable(mySequence);
      return seqTable; 
    }
    

    * Nicht thread-safe mit MSVC.
    * Nicht thread-safe mit C++03.
    * OK mit GCC.



  • hustbaer schrieb:

    brotbernd schrieb:

    -> construct on first use idiom

    int  getSequence( ) const 
    {
      static SeqTable seqTable; 
      return seqTable( mySequence ); 
    }
    

    * Falsche Syntax
    ->

    int getSequence() const 
    {
      static SeqTable seqTable(mySequence);
      return seqTable; 
    }
    

    * Nicht thread-safe mit MSVC.
    * Nicht thread-safe mit C++03.
    * OK mit GCC.

    Also einer von uns beiden guckt schief. SeqTabl hat einen ()operator, keine int Konvertierung und auch keinen solchen Ctor.



  • Ja, ICH gucke schief 😃
    Sorry, hast natürlich Recht.

    Thread-safety ist aber so wie beschrieben.



  • Dazu eine Frage:
    - nicht thread-safe vermutlich weil ein zweiter thread getSequence aufrufen könnte, während das Objekt noch konstruiert wird (aufgrund eines Aufrufs von getsequence durch ersten thread)?

    Inwiefern ist das für G++ in Ordnung? Hat er diesbezüglich erweiterete Sicherheitsmechanismen?



  • Ja und Ja.
    lokale static Initialisierungen sind im GCC thread safe.



  • inter2k3 schrieb:

    - nicht thread-safe vermutlich weil ein zweiter thread getSequence aufrufen könnte, während das Objekt noch konstruiert wird (aufgrund eines Aufrufs von getsequence durch ersten thread)?

    Genau das. Dabei kann es dann passieren dass der 2. Thread anfängt seinerseits ebenfalls das Objekt zu initialisieren, oder dass der 2. Thread anfängt mit dem Objekt zu arbeiten, obwohl es noch nicht fertig initialisiert ist.

    Inwiefern ist das für G++ in Ordnung? Hat er diesbezüglich erweiterete Sicherheitsmechanismen?

    Auch richtig. G++ macht da im Prinzip das Äquivalent von boost::call_once rein um die statische Variable zu initialisieren. Da sich der check auf den meisten Plattformen so implementieren lässt, dass der "bereits initialisiert" Fall extrem schnell läuft, ist der Performance-Impact minimal.



  • @minastaros:
    Wenn du C++0x benutzt und dein Singleton thread-safe machen möchtest,
    kannst du dir ja mal die Variante 1 hier ankucken (bei Variante 2 wurde mir die thread-safety nicht bestätigt):
    http://www.c-plusplus.net/forum/279968#2004357



  • Hallo zusammen,

    vielen Dank für die vielen Anmerkungen, das first use idion werd ich nochmal näher anschauen. Wie gesagt, funktionieren tut es und in der derzeitigen Umgebung (embedded-Gerät) ist thread-safeness an dieser Stelle (noch) kein Problem, da die Threads ganz gezielt erzeugt werden und auf die Resourcen zugreifen.

    Werde bei Gelegenheit mal mehr in Richtung Singleton verbessern. Xspille, auch vielen Dank für den Vorschlag. Ist das Double-Checked-Locking-Pattern, da hab ich ganz frisch was im Alexandrescu drüber geschmökert, der natürlich gleich auch den Mercedes unter den Singletons (bzw. gleich die ganze Familie) mitbringt. Naja, zur Zeit tut es noch mein static ... 😉


Anmelden zum Antworten