Meine liebe Hassliste
-
Einrückung, Planks usw. interessieren mich kaum. Wenn ichs nicht lesen kann, lass ich einfach eine automatische Code-Formatierung drüberlaufen.
Defaultargumente, mhh interessant. Mir ist noch nix nerviges damit untergekommen. Habt ihr ein Beispiel?
Mich nerven besonders ewiglange Funktionen, vorallem wenn da viel ohne RAII gemacht wird und man immer aufpassen muss. Generell eigentlich alles, mit dem man unnötig viel Zeit verbringen muss, nur weil irgendwer zu doof oder gar faul war. Und wenn es dann bei nem Kunden crasht, der ursprüngliche Entwickler aber schon lange nicht mehr da ist, und ich es debuggen darf ...
@TravisG: Weils manchmal Spaß macht, sich zu ägern.
-
...
-
TravisG schrieb:
Bin ich der einzige, der keine Hassliste für fremden Code hat?
Ja, könnte sein.
Fremden Code zu debuggen ist so unglaublich schwieriger als eigenen zu debuggen...
So unglaublich viel aufwändiger. Faktor 4, wenn der andere extrem gut ist, so gut wie Bashar, Shade oder so.
Kann aber gerne mal auf 10 oder exorbitant gehen.TravisG schrieb:
Warum soll man sich über sowas aufregen?
Wir Programmierer regen uns doch nicht auf wegen sowas. Wir können hassen, ohne, daß der Blutdruck steigt. Sonst wären wir alle tot.
Wenn ich wiedermal als Admin was mache, dann ist es schon fast regelmäßig, daß der Kunde sehr gut vorgebildet ist, wie man mit Rechnern umgeht. Ich mache genau das, was er auch tun würde, nur gebe ich nicht nach 20 Minuten auf, sondern kämpfe mich durch, selbst wenn es 2 Stunden dauert. Wiedermal von MS und Adobe Steine in den Weg gelegt kriegt, die Hardware von der Bezugsstelle taugt nix, der im Unternehmen zwangsweise eingesetze Virenscanner ist dummkonfiguriert...
Na, und?
Die ersten Programme hinzukriegen war viel unergiebiger. Die ersten Speicherlöcher in C zu stopfen, allein sie zu erkennen!
Ich löse also sein Problem. Und er schaut mich mit großen Augen an. Gibt zu, daß er schon drei Fachleute vorher befragt hatte, die aufgegeben hatten.Einfach dran bleiben. Und insbesondere so lange fummeln und frickeln, bis ein Geistesblitz kommt. Der kommt nicht von alleine, sundern dadurch, daß man dran bleibt und sich reinvertieft.
Am Ende habe ich nur gemacht, was der Kunde auch hätte machen können, nur ich rege mich eben nicht auf, sondern frickele mich durch. Und wenn's wieder mal eine besondere Gemeinheit gibt, die ich erkenne, dann lache ich, zeige auf den Bildschirm und lache die Gemeinlinge aus. Letztendlich sichern die Gemeinlinge, Laientreiberprogrammierer und Lügedokumentierer ja auch, daß Informatiker immer mal einen schnellen Euro machen können.
-
volkard schrieb:
new statt vector weil evtl schneller
Da vector alles initialisiert, kann unique_ptr<T[]> uU durchaus schneller sein.
-
Swordfish schrieb:
hustbaer schrieb:
* Plenken
funktion ( parameter );
Fällt
if( !foo ) { bar( 43 ); }
in das Schema?
Das ist doch hübsch.
Ich würde schreiben
if(!foo){ bar(43); }
also antiplenk.
Kaputt wird es bei
if (!foo) { bar (43); }
Ich kann mich nicht entscheiden, wohin mit den Spaces.
if ( ! foo ) { bar ( 43 ) ; }
?
Nee.if( !foo ) { bar( 43 ); }
Nee.
if( !foo and !bar ) { bar( 43 + 5*7 - 3 + pow ( 10 , 3*2 ) ); }
Nee. Stattdessen stelle ich in der IDE die Schriftart groß, sehr groß, ungemein groß, das würdet Ihr nicht glauben. Für mich ist das der beste Weg.
-
cooky451 schrieb:
volkard schrieb:
new statt vector weil evtl schneller
Da vector alles Initialisiert, kann unique_ptr<T[]> uU durchaus schneller sein.
Kennst Du push_back?
Ok, der Zeiger kann schneller sein. push_back verbrät eine Inkrementierung und eine Fallunterscheidung pro Einfügung, 2 Takte?
Falls man mit den Daten dann was berechnet, ist es vollkommen Latte, was push_back kostete.Und ich bin ein Freund davon, sich selber Container zu schreiben, die halt an das Problem noch besser angemessen sind als die Standardcontainer. Bei vector<T> zum Beispiel habe ich eine Alternativ-Implemetierung Vector<T,size_t>, die intern nicht new benutzt, sondern ein std::array. Manchmal, ganz ganz selten, bläst das ganz gut. Vorstellbar als Container, der zu eriner Schach-Stellung die möglichen Züge aufnimmt. Aber fast immer ist vector echt vollkommen ok und kein zehntel Prozent Performance-Nachteil kann befürchtet werden.
Wer zerstört im Exception-Fall die Objekte, die per placement-new in den unique_ptr<T[]> gestopft wurden?
-
Du denkst da an den falschen Anwendungsfall. Manchmal will man einfach nur 100 MB Speicher am Stück haben, der dann später beschrieben wird - std::vector fährt da dann erstmal mit einem memset drüber. Aber ja, die Anwendungsfälle halten sich schon in Grenzen, ist nur etwas, das mir eingefallen ist.
-
cooky451 schrieb:
Du denkst da an den falschen Anwendungsfall. Manchmal will man einfach nur 100 MB Speicher am Stück haben, der dann später beschrieben wird - std::vector fährt da dann erstmal mit einem memset drüber. Aber ja, die Anwendungsfälle halten sich schon in Grenzen, ist nur etwas, das mir eingefallen ist.
Ja, dafür dann den MemoryPool. Apache macht es vor. Wobei der Hauptvorteil davon ist, daß kein Destruktor befragt wird.
Daß vector aber die 100MB vorher nullen wüprde, ist schlicht falscht.
vector<char> v(100000000) tut es. Und dann reinkopieren mit v[i++]=c;
Aber das fast immer bessere
vector<char> v; nebst v.push_back(c);
ist davon frei.
-
cooky451 schrieb:
Du denkst da an den falschen Anwendungsfall. Manchmal will man einfach nur 100 MB Speicher am Stück haben, der dann später beschrieben wird
Und ohne ihn zu nullen? Dann geht doch push_back perfekt. Wir konstruieren einfach hinein.
Ähm, ob ich den i++ selber führe oder der vector. Ja, Registerdruck, falls i ind c.size() immer gleich sind. Falls ungleich, ist es schon recht egal.Oder DU willst ausnutzen, daß auf Deinem BS der allokierte Speicher schon genullt ist? Nee, so fies bist Du nicht, das weiß ich.
-
Na ja, angenommen du willst 100 MB binäre Daten einfach am Stück in den Speicher schaufeln (aus einer Datei z.B.) - da ließt du doch nicht immer ein byte auf einmal und pushst das dann in der vector?
-
...
-
Swordfish schrieb:
volkard schrieb:
[...]
Aha. Also
if(foo()){ bar(42) }
.
Und noch vier- bis fünfmal [Strg]+[+] drücken bitte.
-
cooky451 schrieb:
Na ja, angenommen du willst 100 MB binäre Daten einfach am Stück in den Speicher schaufeln (aus einer Datei z.B.) - da ließt du doch nicht immer ein byte auf einmal und pushst das dann in der vector?
Naja, vielleicht benutzue ich dann Filemapping und fresse gar keinen Speicher weg.
Aber jo, ein "Container" für nicht konstruierten Speicher, der fehlt irgendwie.
-
if( x < y){ //... } else { //... }
liest sich beschissen.
-
- eigenen vektor definieren, weil er "besser" ist als der Standard
- wegen Formatierung eine Diskussion anfangen als gäbe es nicht wichtigeres
-
Meine unvollständige Hassliste, sortiert nach Kategorie.
Ressourcenleck
- Destruktoren, die mehrere Ressourcen manuell freigeben (weil starkes Anzeichen für Lecks beim Anfordern)delete
,delete[]
,free
,myPrefix_Free
- Nichtverwendung von Initialisierungslistendestroy()
-Methode statt Destruktor
- Verwendung von nicht-trivialen C-Bibliotheken ohne irgendwelche Wrapperexit
Undefiniertes Verhalten
- reservierte Bezeichner (besonders gerne als_INCLUDE_GUARD_H_
)
- Missachtung von strict aliasing oder alignment
- falsche Verwendung vonunion
signed
Overflow
Unnötige Gefahr / Obfuscation
#define
für Konstanten
- globale/statische Variablen
- Annahme, dasssizeof(int) == sizeof(long) == 4
etc.
- C-Casts
- magische Zahlenint
oderunsigned
, wenn eigentlichptrdiff_t
odersize_t
gemeint ist
- riesige Klassen in riesigen Dateienstrcpy
,strlen
,atoi
,fopen
,memcpy
usw.s/f/printf
- geschweifte Blockklammern bei Einzel-Statements weglassen
- Klassenmember in einem#ifdef
(endet immer in kaputtem Build oder undefiniertem Verhalten)
- Statements in#ifdef
- Kommaoperator statt Statements
Voodoo
- Werte im Destruktor in Nullzustand setzen (v.clear()
,p = nullptr
etc.)
- "safe delete"-Makros oder -Funktions-Templatesif (p) { delete p; }
inline
bei Definition in cpp-Datei
- lokale Arrays, wovector
oderstring
besser geeignet wärentypedef struct
Unwissenheit
ntohl
,ntohs
und sostruct
zur "Serialisierung"
- Verwendung vonstd::list
, wennstd::vector
gemeint istthrow new
- C-Standard-Header einbinden
- Spaces zum Einrückenwhile (!feof(f))
und ähnliche Abenteuer
In den meisten Projekten finden sich leider die meisten dieser Punkte.
-
Swordfish schrieb:
hustbaer schrieb:
* Plenken
funktion ( parameter );
Fällt
if( !foo ) { bar( 43 ); }
in das Schema?
Ja.
Das sind 3 Sachen auf einmal, wobei ich eins vergessen hatte hinzuschreiben: "ifs" wo die bedingte Anweisung (bzw. der Block) in der selben Zeile mit dem "if" steht.Also Schritt für Schritt...
Zwei Zeilen draus machenif( !foo ) bar( 43 );
Plenks entfernen
if(!foo) bar(43);
Fehlendes Leerzeichen nach dem Keyword einfügen
if (!foo) bar(43);
Tadaa
-
TyRoXx schrieb:
Ressourcenleck
- Destruktoren, die mehrere Ressourcen manuell freigebenDer Destruktor ist dabei ja nicht das Problem, sondern der (meist nicht Exception-sichere) Konstruktor den man dazu braucht.
Aber guter Punkt grundsätzlich. Ganz schlimm: Code der fleissig Exceptions verwendet, aber an 1000 Stellen nicht Exception-sicher ist.
-
TyRoXx schrieb:
- Destruktoren, die mehrere Ressourcen manuell freigeben (weil starkes Anzeichen für Lecks beim Anfordern)
Sehr schöner Punkt und immer wieder ein relativ gutes Zeichen für halb verstandenes RAII.
TyRoXx schrieb:
Missachtung von strict aliasing
Da fehlt noch Alignment. Aber wenn jemand speziell für eine Plattform programmiert ist das schon okay denke ich. Strict aliasing scheint eh niemand so richtig zu verstehen.
TyRoXx schrieb:
strcpy
,strlen
,atoi
,fopen
,memcpy
usw.
memcpy ist schon okay denke ich. Auch an fopen sehe ich grundsätzlich nichts Falsches, wenn es ordentlich gekapselt ist.
TyRoXx schrieb:
- geschweifte Blockklammern bei Einzel-Statements weglassen
Wie sieht's hiermit aus?
for (unsigned i = its + 1; --i != 0; ) if (foo(i) == its) return bar(++i), baz(its), i;
TyRoXx schrieb:
- lokale Arrays, wo
vector
oderstring
besser geeignet wärenOder std::array? Man sollte die Vorzüge des Stacks nicht so oft missen, finde ich.
-
cooky451 schrieb:
TyRoXx schrieb:
strcpy
,strlen
,atoi
,fopen
,memcpy
usw.
memcpy ist schon okay denke ich.
Mir sind die impliziten Konvertierungen zu
void *
zu gefährlich.
Beistd::copy
kann der Compiler viel leichter Fehler entdecken.cooky451 schrieb:
Auch an fopen sehe ich grundsätzlich nichts Falsches, wenn es ordentlich gekapselt ist.
Wie wäre es mit
i/o/fstream
?cooky451 schrieb:
TyRoXx schrieb:
- geschweifte Blockklammern bei Einzel-Statements weglassen
Wie sieht's hiermit aus?
for (unsigned i = its + 1; --i != 0; ) if (foo(i) == its) return bar(++i), baz(its), i;
Stimmt, den Kommaoperator habe ich vergessen.
cooky451 schrieb:
TyRoXx schrieb:
- lokale Arrays, wo
vector
oderstring
besser geeignet wärenOder std::array? Man sollte dir Vorzüge des Stacks nicht so oft missen, finde ich.
Wenn die Größe wirklich klein und fest ist, kann man
std::array
verwenden.
Wenn die Größe variabel und nur selten zu groß für den Stack ist, kann man sich einsmall_vector<T, N>
-Template schreiben.
Ansonsten möge man einen dynamischen Standard-Container nehmen.