Der this-Zeiger im if
-
Nexus schrieb:
volkard schrieb:
Ich fürchte, das muss man nur machen, wenn man das Gesamtkonzept verloren hat und versucht, Zugriffsfehler im Nachhinein an den Symptomen zu heilen.
Sehe ich auch so. Generell halte ich die Notwendigkeit, Zeiger immer gleich sofort auf Null zu setzen (nach
delete-- oder noch schlimmer -- im Destruktor) und jeweils zu prüfen, für fragwürdig. Oft ist das ein Hinweis darauf, dass man sich über die Gültigkeit seiner Zeiger nicht im Klaren ist.Auch wenn ich es ebenso sehe: Wenn man Altcode übernimmt, und nicht die Zeit für eine saubere Korrektur bekommt, ist so etwas dennoch ein Weg um Fehler zu finden.
Ich habe mehr als einmal an einer "historisch gewachsenen" Anwendung gearbeitet, und nur in seltenen Fall (wie z.B. in meiner aktuellen Firma) erhält man auch die Zeit um Code wirklich zu korrigieren (selbst wenn man es wohl dennoch versucht, geht dies ansonsten nur immer Häppchenweise).
Ich kenne Projekte bei dem ein Programmierchef der Meinung das alles möglichst public und static zu deklarieren und hat solche Variablen auch doppelt und dreifach zu verwenden. Und dies galt auch für Zeiger (wenigstens konnte man davon ausgehen das diese wenn Objekte gelöscht wurden sind genullt wurden, so das man diese gegen null prüfen konnte). Dies ganze wurde noch dadurch verschlimmbessert, dass der zudem die Meinung galt, das der Benutzer keine Fehlermeldungen sehen sollte (lieber mal auf gewissen Inkonsistenzen weiter arbeiten). Ich habe eines für mein Leben gelernt: Wenn ich jemals wieder an so ein Projekt komme werde ich aktiv umgehend eine neue Stelle suchen.
-
Ich meinte meine Aussage generell, nicht auf dd+ bezogen. Ja, Legacy-Code ist natürlich immer mühsam, aber ich habe Sachen wie
SAFE_DELETEauch schon genügend oft in neuem Code gesehen.Ohnehin würde ich hier kein
ifverwenden, sondernassert(wenn ich mich in so einer Situation befände, normalerweise prüfe ich natürlich nicht aufthis-Gültigkeit). Wobei das natürlich Projektmanagern, die lieber mit Fehler weiterarbeiten, nicht gefallen könnte...
-
Aber zur Sicherheit noch einen catch(...)-Block drumherum!
-
Decimad schrieb:
Aber zur Sicherheit noch einen catch(...)-Block drumherum!
Hier die Datei "IchBinEineWaschmaschine.hpp"
#define main real_main #indlude "IchMagJava.hpp"Und die "IchBinEineWaschmaschine.cpp"
int main() { for(;;) try { int real_main(); return real_main(); } catch(...) { } }
-
Nexus schrieb:
Soweit richtig?
Nein. Der Wert von t ist nach den Zuweisungen durch
0,NULLundnullptrjeweils derselbe. Das MakroNULList in C++ gerade als0definiert,nullptrist die typsichere C++11-Variante.[/quote]Ich nutze das mal als Gelegenheit eine Frage zu stellen:
Was genau bringt "nullptr" für Vorteile gegenüber "NULL" oder "0" ? ( ist ernst gemeint ).
-
It0101 schrieb:
Was genau bringt "nullptr" für Vorteile gegenüber "NULL" oder "0" ? ( ist ernst gemeint ).
Irgendwie ist der Typ int da falsch.
#include <iostream> char const* mySecret="geheim"; template<typename T,typename U> bool test(T const t,U const u){ return t==u; } int main() { using namespace std; if(mySecret==0) cout<<"no secret\n"; if(test(mySecret,nullptr)) cout<<"no secret\n"; if(test(mySecret,0))//klappt seltsamerweise nicht cout<<"no secret\n"; }
-
Das hat diese Vorteile:
1. Es hebt die Doppeldeutigkeit der 0 auf (auch wenn diese aus Gründen der Abwärtskompatibilität weiterhin besteht, so sollte aber doch zumindest in neuem Code mit 0 immer eine Integer-Konstante gemeint sein).
2. nullptr ist von einem Pointertyp und somit nicht mehr in einen Ganzzahltyp (außer bool) konvertierbar.
3. Noch schlimmer als 0 war NULL, da es sich so anfühlte, als hätte es die Vorteile 1 und 2, aber in Wirklichkeit war das gar nicht so, da NULL in C++ als 0 definiert ist. Daher war folgende verwirrende Überladungsauflösung möglich:void foo(int); void foo(void*); ... foo(NULL); // Ruft foo(int) aufDas kann mit nullptr nicht passieren.
-
Danke euch. Das leuchtet mir durchaus ein, wenngleich ich der Meinung bin, dass die Vorteile nicht ganz so groß sind, wie der Aufriss, der hier im Thread gemacht wird

-
...
-
It0101 schrieb:
Das leuchtet mir durchaus ein, wenngleich ich der Meinung bin, dass die Vorteile nicht ganz so groß sind, wie der Aufriss, der hier im Thread gemacht wird

Ist das gleiche wie mit
std::arrayoder RAII: Du hast Null Kosten, wenn dunullptrbenutzt -- nur Vorteile. Es wäre dumm, bei einem C++11-kompatiblen Compiler noch0oderNULLfür Zeiger einzusetzen.
-
It0101 schrieb:
Danke euch. Das leuchtet mir durchaus ein, wenngleich ich der Meinung bin, dass die Vorteile nicht ganz so groß sind, wie der Aufriss, der hier im Thread gemacht wird

Jo, ich hatte noch nie einen Fehler wegen 0 zu suchen.
Also der Aufriß im Sinne von "Nehmt sofort nurnoch nulltptr, sonst werden wir alle serben!" ist sicher übertrieben.
Vielleicht folgt bald im Thread "Würdest Du an wirklich großen Projekten arbeiten, dann wärst Du meiner Meinung.". Dann wird es religiös.Aber da wir nullptr schonmal haben, sollte man ihn auch nehmen, weil kostet ja nix und könnte irgendwann mal ein Viertel Stündchen sparen.
Öhm. Nö, dann muss man das Mehr an Tipparbeit rechnen und 0 ist besser.
Anderer Grund: Man muss sich nullptr angewöhnen, weil sich die deutlich überwiegende Mehrheit der Gemeinde es auch angewöhnt. Dadurch kann man Fragen mit Querllcode posten, ohne daß der Thread reflexartig fünf bis acht wohlmeinende Hinweise auf nullptr fängt und die Hauptfrage fast untergeht.
-
Ich muss gar nichts. Ich arbeite mit memset, damit bin ich bei 90% der Member ohnehin unten durch. Den nullptr werde ich trotzdem verwenden, weil es ja in der Tat nichts kostet.
-
It0101 schrieb:
Ich muss gar nichts. Ich arbeite mit memset, damit bin ich bei 90% der Member ohnehin unten durch.
Jo. Das sagt, daß Du Dir seit Jahren Dein Compilat nicht mehr angeschaut hast.
Der optimierende Compiler erkennt memsettende Schleifen von selber und optimiert genau gleich wie intrinsisches memset.
-
volkard schrieb:
Also der Aufriß im Sinne von "Nehmt sofort nurnoch nulltptr, sonst werden wir alle serben!" ist sicher übertrieben.
Solange ich mir aussuchen darf wo ich lebe werde ich auch Serbe.
-
LordJaxom schrieb:
volkard schrieb:
Also der Aufriß im Sinne von "Nehmt sofort nurnoch nulltptr, sonst werden wir alle serben!" ist sicher übertrieben.
Solange ich mir aussuchen darf wo ich lebe werde ich auch Serbe.
Ein albaner Witz.

-
beispiellos schrieb:
Eine Referenz auf 0 ist nicht per se UB, erst wenn auf sie irgendwie zugegriffen wird.
Das ist ein bisschen unpräzise. Die Dereferenzierung von 0 ist erlaubt, der Begriff Referenz aber hier fehl am Platz, denn natürlich ist es UB, einen so dereferenzierten Nullzeiger zum Initialisieren einer Referenz zu verwenden (weil es eben keine Initialisierung mit einem Objekt ist).
-
volkard schrieb:
Der optimierende Compiler erkennt memsettende Schleifen von selber und optimiert genau gleich wie intrinsisches memset.
Bei memset muss ich weniger tippen und ich spar mir ne Schleife die den Code unnütz verunstaltet. Gleiches gilt für memmove, memcmp, memcpy, etc ...
Aber so viele Anwendungsfälle gibt es ja dafür ohnehin nicht, weil die Menge an PODs bei mir seit einiger Zeit rückläufig ist

-
volkard schrieb:
It0101 schrieb:
Danke euch. Das leuchtet mir durchaus ein, wenngleich ich der Meinung bin, dass die Vorteile nicht ganz so groß sind, wie der Aufriss, der hier im Thread gemacht wird

Jo, ich hatte noch nie einen Fehler wegen 0 zu suchen.
Du glücklicher... Mich hat dies einmal mehrere Tage gekostet, einen solchen Fehler zu finden und zu verstehen (Damals war mir die Problematik noch nicht so bewusst).
Wenn der Compiler hier nullptr unterstützen würde, wäre es bei uns sicherlich eine feste Regel, diesen statt 0 zu verwenden. Nicht weil der Fehler unbedingt häufig wäre, aber die "Kosten" wenn dieser mal auftritt recht hoch sein können.
Nur weil etwas bisher noch kein Problem gemacht hat, würde ich dennoch eine sichere Variante, wenn vorhanden, immer vorziehen.
-
SeppJ schrieb:
3. Noch schlimmer als 0 war NULL
Hat allerdings den Vorteil, dass -sofern niemand totalen Mist macht und NULL für was anderes als Pointer verwendet- man mit einem replace schnell alle NULLs durch nullptrs ersetzen kann.
-
Mir scheint, memset mag keine mmx-Befehle benutzen.