Meine liebe Hassliste



  • Hallo 🙂

    Wenn man so verliebt ist in eine Sprache das eher diese bedient wird
    als der Anwender und/oder Computer.
    ("Zu jeder Tätigkeit das passende Werkzeug benutzen")

    Das es im Internet keinen update-Button gibt
    und sich dadurch falsche Annahmen/Code soweit verbreiten
    bis jeder glaubt es wäre der richtige Weg.
    ("Mehrfache Wiederholung machen Unwahrheiten kein bischen wahrer")

    Ohje 😃



  • Dinge die ich nicht mag:
    * Fehlende Dokumentation
    * Dateipaare welche eigentlich in mehrere Dateien zerfallen sollten, aber wo man diese der "Übersichtlichkeit" halber in eine Datei gepackt hat
    * Fehlende Trennung der Funktionalitäten s.d. diese man auch Allgemeiner benutzt werden könnte.

    void CryptAndWriteData(FILE* File, const char* Data, const char* Key)
    {
      while (*Data)
      {
        fprintf(File, "%c", *Data ^ Key[i]);
        Data++;
        i = (i + 1) % strlen(Key);
      }
    }
    

    * Mehrere Anweisung in einer Zeile (schlecht zu debuggen)
    * Mikro-Optimierungen nach dem Motto: Ich weis es besser als der Compiler.
    * Übergabe von Funktionsparameter mittels globalen Variablen:

    void OpenPortAndGetData(void);
    

    * Globale Variablen, wenn diese an Funktionen gebunden sind.
    * Statische Variablen innerhalb einer Funktion
    * Makro's
    * Fehlende Typsicherheit:

    unsigned char Sprache;
    //...
    if (Sprache == DEUTSCH)
    //...
    
    void Test(unsigned int Flags)
    {
    //...
      Test2(Flags)
    }
    

    * exit
    * Allokierung von Resourcen welche nicht freigegeben wurden, da Windows diese ja automatich freigibt
    * char*, char s[37]
    * Zugriff auf statische Array's ohne Überprüfung eines Überlauf's
    * Statische Array's wo eigentlich std::vector
    * Fehlende Const Correctness
    * CRT
    * "Never change a running system" bis zum Exzess



  • Bitte ein Bit schrieb:

    * exit

    Ich hatte neulich exit benutzt, damit das Programm nach Berechnung des Ergebnisses nicht noch Minutenlang den Speicher aufräumt. 🕶



  • Ich hatte neulich exit benutzt, damit das Programm nach Berechnung des Ergebnisses nicht noch Minutenlang den Speicher aufräumt.

    Kommt halt immer auf den Fall an.

    Ich habe es erlebt das man exit() in einer Error-Funktion benutzte. Trat ein Fehler auf, wurde die Funktion aufgerufen und peng. Dumm nur, Zwischenergebnisse, welche in einer Datei geschrieben wurden, waren weg, obwohl diese sehr bruachbar waren.

    Übrigens:
    Was muss man tun damit man minutenlang Speicher aufräumt? Wieviel GByte swappst du da?



  • Bitte ein Bit schrieb:

    Was muss man tun damit man minutenlang Speicher aufräumt? Wieviel GByte swappst du da?

    Man muss einfach nur ohne Ende Mini-Allocations machen, das reicht schon. Wenn man exit() aufruft wird der Speicher von Windows allerdings mehr oder weniger instant freigegeben.



  • Im Produktionscode von Arbeitskollegen:

    void FOO()
    {
       if( abc )
       {
          some_type* x;
          x = NULL;
          x = new some_type();
          if( x )
          {
             ...
          }
       }
    }
    
    int abc;
    
    void bar()
    {
       abc = 7;
       FOO();
    }
    

    Der Quelltext ist mehrere tausend Zeilen lang, hin- und wieder werden globale Variablen zwischen Funktionsrümpfen untergebracht, da können aber auch einige hundert Quelltextzeilen zwischen Deklaration und Benutzung liegen.



  • Bitte ein Bit schrieb:

    Was muss man tun damit man minutenlang Speicher aufräumt? Wieviel GByte swappst du da?

    ca 60G in einer map<int,vector<int>>.



  • volkard schrieb:

    Quatsch-Optimierungen wie >>1 statt /2, inline-asm für Sachen, die der Compiler viel besser kann, new statt vector weil evtl schneller, Schleifenvariable i als char statt int, um Bits zu sparen...

    Trifft der Quatsch auf <<1 für *2 auch zu?



  • cooky451 schrieb:

    TyRoXx schrieb:

    Mir sind die impliziten Konvertierungen zu void * zu gefährlich.
    Bei std::copy kann der Compiler viel leichter Fehler entdecken.

    Hm, sehe ich nicht unbedingt so. memcpy sagt ja gerade "schreib einfach in den Speicher". std::copy ist da nur bedingt ein Ersatz. z.B. hier:

    void foo(const void* data, std::size_t size)
    {
      int s;
      memcpy(&s, data, sizeof s);
      // vs
      copy(static_cast<const uint8_t*>(data), static_cast<const uint8_t*>(data) + sizeof s, reinterpret_cast<uint8_t*>(&s));
    }
    

    Zuerst würde ich den richtigen Zeigertyp verwenden, nämlich const char * . Damit fallen zwei der drei Casts schon weg. Der reinterpret_cast kann da gerne als Hinweis auf implementationsdefiniertes Verhalten stehen bleiben.
    So etwas braucht man extrem selten, wenn überhaupt. Da finde ich es nicht zu viel verlangt, den Cast zu tippen.



  • Wenn man SHA/AES etc. implementiert, braucht man sowas quasi die ganze Zeit, da finde ich den Cast doch zu nervig. 😉 Abgesehen davon schreit const char* nach C-String, daher finde ich es eher unpassend. const void* sagt: Einfach nur Speicher, völlig egal was drin steht.



  • Huch, ich finde ein Leerzeichen nach if oder for aber nicht schön.



  • Eisflamme schrieb:

    Huch, ich finde ein Leerzeichen nach if oder for aber nicht schön.

    Das ist mittlerweile aber schon üblicher als dort kein Leerzeichen zu machen. 😉



  • Okay, also geht es hier um Gewohnheit. Ergibt ja auch Sinn.

    if (a == b)
    

    Ich finde hier aber, dass der Ausdruck irgendwie losgekoppelt vom if wirkt. So wie (a == b) und weiter? Ach, da steht ja links noch "ganz verloren" ein if.

    Ich meine, die Schreibweise ähnelt für mich der Funktionsschreibweise. Niemand fordert f(x) als f (x) zu schreiben, oder? Das wäre ja seltsam.

    Und das hier ist zwar keine Funktion, aber warum sollte man hier ein zusätzliches Leerzeichen einfügen? Finde ich erstmal un-intuitiv (<- wieso gibt es hierfür kein deutsches Wort?)



  • Nein.
    In C++ werden Variablen erst dann deklariert, wenn sie verwendet werden.
    Laut deiner Theorie kann ich ja alles in den globalen Namespace packen und gut ist.



  • TravisG schrieb:

    Bin ich der einzige, der keine Hassliste für fremden Code hat? Jeder der hier drin seine Hassliste auflistet, hat in seinem Code Sachen, die bei jemand anderem in ner Hassliste stehen.

    Warum soll man sich über sowas aufregen?

    Es wäre darüberhinaus sinnvoll, diese Hasslisten mal alle in einer Wiki zu vereinen und ihre Pros und Contras anzuführen, falls es verschiedene Meinungen geben sollte.

    Dadurch wäre das ganze hier wenigstens produktiv.



  • Nathan schrieb:

    Nein.
    In C++ werden Variablen erst dann deklariert, wenn sie verwendet werden.
    Laut deiner Theorie kann ich ja alles in den globalen Namespace packen und gut ist.

    Nein, sie gehören an den Anfang (z.b. dem Beginn der Funktion).

    Das tut man für den Programmierer, damit der eine Übersicht hat, welche Variblennamen überhaupt deklariert wurden und warum es sie gibt.

    Variablen irgendwo mitten in der Funktion zu deklarieren ist schlechter Programmierstil und das hat nichts mit C++ zu tun, sondern gilt für jede Sprache.



  • lol, ein Pascal-Troll. 😃

    class SuperHeavyObject
    {
        // Braucht 10 Sekunden zum Erzeugen und 5 zum Zerstören und frisst 100MB RAM.
    };
    
    void Foo()
    {
        SuperHeavyObject obj;
        if (condition)
            return;
        obj.Bar();
    }
    
    void Foo()
    {
        if (condition)
            return;
        SuperHeavyObject obj;
        obj.Bar();
    }
    

    Na? 😉



  • Dobi schrieb:

    lol, ein Pascal-Troll. 😃

    class SuperHeavyObject
    {
        // Braucht 10 Sekunden zum Erzeugen und 5 zum Zerstören und frisst 100MB RAM.
    };
    
    void Foo()
    {
        SuperHeavyObject obj;
        if (condition)
            return;
        obj.Bar();
    }
    
    void Foo()
    {
        if (condition)
            return;
        SuperHeavyObject obj;
        obj.Bar();
    }
    

    Na? 😉

    Lerne den Unterschied zwischen Variablendeklaration und Initialisierung.



  • Lerne RAII kennen.
    Variablendeklaration ist Initialisierung.
    Wozu gibt es sonst Konstruktoren?

    Edit: Wozu gibt es in C++ sonst das Schlüsselwort auto?
    Bei der Deklaration ist es sinnfrei, bei der Initialisierung nützlich.



  • nope7777 schrieb:

    Lerne den Unterschied zwischen Variablendeklaration und Initialisierung.

    Meinst du sowas?

    void Foo()
    {
        SuperHeavyObject* obj;
        if (condition)
            return;
        obj = new SuperHeavyObject;
        obj->Bar();
        delete obj;
    }
    

    Nein, das ist eben genau das, was ich nicht haben will.

    Edit: Nathan hat dir schon den richtigen Hinweis gegeben, worum es geht.

    So, und jetzt haben wir aber genug mit Fischen um uns geworfen. 😉


Anmelden zum Antworten