static Variable, Good Practice oder NoGo?



  • Vll. zur Ergänzung zu C++ und weshalb man C++ gegenüber C vorziehen sollte.
    Ich kenne mind. einen gerechtfertigten Anwendungsfall, der in C++ 11 sogar thread-safe ist:

    static Singleton& get(){
      static Singleton instance;
      return instance;
    }
    

  • Mod

    Das wirft wieder die Frage nach der Berechtigung von Singletons auf und wie oft dieses Pattern falsch eingesetzt wird, weshalb ich es absichtlich nicht erwähnt habe 🙂



  • Bei MVC ist es sinnvoll, wenn der Controller ein Singleton ist.



  • fairiestoy schrieb:

    Ich finde es nur ein wenig erschreckend, dass über diese Zustände in viel Lehrmaterial gar nicht eingegangen wird.

    Da liegt der Hund begraben.
    C ist erschaffen worden von einem Praktiker-Profi. Der wusste, was er wollte und brauchte. Und konnte mit den "Schwachpunkten" umgehen, weil er sie kannte.
    Ritchie hat C für sich und seine Aufgaben erschaffen. Er hat dabei niemals auf mögliche leichte Erlernbarkeit und Vermeidung von Fallstricken geachtet.
    Und später bei der Standardisierung, als viele (ausschließlich aus dem professionellen Umfeld) diese Sprache auch gerne einsetzen wollten, konnte und wollte man nicht mehr am Sprachdesign rumändern.
    C ist eine Programmiersprache von Profis für Profis.
    C ist keine Lernsprache.
    Irgendwann sind dann aber (leider!) auch Lehrer darauf gekommen, C als Einstieg in die Programmierung zu verwenden, weil sie ja so "schön einfach" aussieht.
    Und da bist du jetzt der Leidtragende.

    fairiestoy schrieb:

    Wie habt Ihr das gemacht? Notwendige Grundtechniken erlernt und irgendwann beim testen/lesen diese Mangel festgestellt (also durch Erfahrung) oder gibt es dort eine andere Möglichkeit?

    Um dir mal die Illusionen zu nehmen:
    egal was dein Lehrer dir sagt: du wirst an einer Schule keine C-Programmierung erlernen, die du später professionell anwenden kannst.
    Dasselbe gilt für die heute (leider!) übliche und auch dir sicher bekannte Variante: Lernen mit Google.
    Gehe nicht mit der Aussage "ich kann C programmieren" in irgendwelche Vorstellungsgespräche. Denke dir dafür ein paar neutrale Aussagen aus.

    In C ist Erfahrung alles. Damit meine ich jahrelange tägliche Erfahrung.
    Tatsächlich habe auch ich ein paar Vorlesungen über C (und anderes) gehört.
    Auf mein oben Gesagtes hat mich damals aber niemand hingewiesen, ich war gutgläubig gegenüber den Dozenten (was ganz natürlich ist), wurde dann aber in der Praxis "abgeholt".

    Hier noch eine professionelle Quelle zum Thema (und mit anderen sinnvollen und professionellen Hinweisen):
    https://www.securecoding.cert.org/confluence/display/c/CON33-C.+Avoid+race+conditions+when+using+library+functions

    Solche hübsche, komprimierte und professionelle Wissensvermittlung gab es zu meiner Anfangszeit leider noch nicht, ich habe mir alles selbst erarbeiten müssen und vieles davon findet man hier (und an sehr wenigen anderen professionellen Stellen im Internet) wieder.



  • @Wutz: Das liest sich wie Werbung. Was kannst du mit C (besser) machen, was du mit C++ nicht machen kannst?!


  • Mod

    ShadowClone schrieb:

    @Wutz: Das liest sich wie Werbung. Was kannst du mit C (besser) machen, was du mit C++ nicht machen kannst?!

    Wo hat er denn was von C++ gesagt? Er hat etwas über die Eigenschaften von C gesagt. Bitte keine Flamewars beginnen.



  • @fairiestory:
    Ich glaube dein Programm ist sogar buggy.

    Nehmen wir mal an, du rufst erfolgreich deine Funktion auf. In diesem Fall gibst du einen Zeiger auf ein dirent Struct (ep Variable) zurück. Ruft man nun die Funktion mit einer anderem Pfad auf, so wird trotzdem im ersten Pfad gesucht. Die dp Variable ist ja static und mit dem Pfad des ersten Funktionsaufrufs initalisiert.

    Ich habe auch einen Verdacht wo der Hund begraben ist. Die ep Variable ist ein Zeiger auf ein dirent Struct. Vermutlich zeigt das Struct auf die dp Variable. Deswegen ist die dp Variable static. Das kannst du auch einfach überprüfen in den du ein closedir(dir) vor dem return ep einfügst.

    PS:
    Variablen der Form int FileType sind für mich ein Graus. Was ist hier erlaubt? Und wo ist definiert?



  • Bitte ein Bit schrieb:

    @fairiestory:
    Ich glaube dein Programm ist sogar buggy.

    Nehmen wir mal an, du rufst erfolgreich deine Funktion auf. In diesem Fall gibst du einen Zeiger auf ein dirent S...

    Moin Bitte ein Bit,

    danke für deine Meldung. Im Bezug auf den Code haben bereits Wutz und SeppJ ausgeleuchtet, dass dies ein Fehlverhalten ist. Die Funktion weiss in diesem Zustand nicht, wann bzw ob ein anderer Pfad angegeben wurde im Laufe beispielsweise eines wiederholten Aufrufs durch eine while-Schleife.

    Aus dem Grund wurde ja auch die Nutzung von übergegebenen Objekten für die Speicherung des Programmzustands für einzelne Teile/Module/wie auch immer vorgeschlagen.

    Zumindest ist es das, was ich bisher aus diesem Thread verstanden habe.

    Was die Angabe des Filetypes angeht muss ich sagen, dass ich hier ein wenig mehr gemurkst habe als eh schon. Das von mir gepostete Beispiel habe ich aus diesem Code-Abschnitt zusammen geschustert:

    http://stackoverflow.com/questions/12489/how-do-you-get-a-directory-listing-in-c

    Danach habe ich versucht, einige Infos zu <dirent.h> zu finden, allerdings konnte ich im betreffenden Header keine Filetype-Definitionen ausfindig machen (oder ich habe den Wald vor lauter Bäumen nicht gesehen). Ich vermute jedoch, dass dies betriebssystemspezifisch ist, da auch der Eintrag der Opengroup hierzu keine Info bereit hält.

    Nach ein bissel printf-Magie mit ep->d_type habe ich bisher nur gesehen, dass es zwar verschiedene positive Zahlen für die jeweiligen Typen gibt, konnte aber keine Begrenzung oder den Typ feststellen. Beispielsweise finde ich in meiner <dirent.h> folgende Definition:

    struct dirent
    {
      long            d_ino;		/* Always zero. */
      unsigned short  d_reclen;		/* Always sizeof struct dirent. */
      unsigned short  d_namlen;		/* Length of name in d_name. */
      unsigned        d_type;		/* File attributes */
      char            d_name[FILENAME_MAX]; /* File name. */
    };
    

    Ich kenne so ein Konstrukt gar nicht. Soll d_type jetzt ein unsigned short oder unsigned char sein? Oder sogar ein unsigned der nativen kleinsten Größe für einen Pointer? Da ich hierzu noch ein bisschen nach der Antwort suchen muss, habe ich erstmal für FileType ein int gewählt (gut, es hätte mindestens ein unsigned int sein sollen, dass sehe ich ein).



  • unsigned bedeutet wenn kein anderer Typ dabei steht immer unsigned int .



  • Ich hab auch schon static in rekursiven Funktionen benutzt und wurde dafür von Martin Richter geschumpfen - Problem war ein ähnliches wie deines, aber ich hab es nur als Zählvariable benutzt.


Anmelden zum Antworten