Gibt es eine GCC-option, um zu warnen, über das schreiben `das Feld` statt `this->Feld`?
Diesem folgenden code (mit einem bösartigen bug) kompiliert mit GCC ohne jede Vorwarnung. Aber, natürlich, es funktioniert nicht wie erwartet durch den Entwickler (mich).
#include <iostream>
struct A
{
bool b;
void set(bool b_) { this->b = b_; }
bool get() const { return this-b; } //The bug is here: '-' instead of '->'
};
int main()
{
A a;
a.set(true);
std::cout << a.get() << std::endl; //Print 1
a.set(false);
std::cout << a.get() << std::endl; //Print 1 too...
return 0;
}
Die Warnung kann ich für den compiler (GCC-4.8) zu vermeiden, diese Art von typo?
Verlinkten Frage: gibt es eine Möglichkeit zu zwingen (oder warnen) der Zugriff auf member-Variablen/Funktionen mit this->
?
- Was ist, wenn einige seltsame Person will, abzüglich der
this
Zeiger durch einen booleschen Wert? Sollte er eine Verwarnung bekommen? - Vielleicht können Sie nicht. In einigen seltsamen Fällen wird Ihr code macht Sinn
- Wenn Sie aktiviert haben die hypothetische Warnung option, die OP fragt, dann ja.
- Dies ist richtig, C++ - Satz, also kein compiler erzeugt eine Warnung. Sollten Sie die Verwendung von statischen code-Analyse-tool statt.
- meinen Sie nicht, Sie sollten? Sie könnten schalten Sie immer die Warnung, dass, wenn Sie wissen, dass ist wirklich das, was Sie tun wollen
- Ich könnte mir vorstellen
-Wconversion
(implizite Konvertierung Warnungen), als Zeiger implizit in bool - aber das hat es nicht bekommen... - die meisten Compiler erzeugen Warnungen für "richtige" C++ - Sätze. Zumindest bei der Verwendung von expliziten Warnung Optionen.
- Ich bin mir ziemlich sicher, dass es keine Warnung für diesen, jeden einzelnen Vorgang hier ist Recht sinnvoll in einem bestimmten Kontext.
- Das ist die ganze Zeit in der realen Welt code, wie
if(p && p->bla)
würden Sie nicht warnen, dass für. - Ich denke, dies zeigt perfekt, warum unit-Tests Wert hat.
- Nicht alltäglich für die Werte zurückgeben...
- Wie über Warnung für das tun von Zeiger-Arithmetik auf
this
? Ich hätte nichts dagegen, eine solche option Warnung obwohl vielleicht nicht in-Wall
. - Das würde Sinn machen in meinen Augen. Offenbar niemand sah, dass Sie als groß genug, ein Problem so weit, aber ich würde nicht dagegen, dass die Warnung entweder.
- Vielleicht möchten Sie versuchen
-Waddress
(die aktiviert ist, indem Sie-Wall
) und warnt davor, verdächtige Verwendungen von Speicher-Adressen. Allerdings bin ich zweifelhaft - Konvertierung von bool zuint
ist gut definiert, Zeiger-Arithmetik (addition/Subtraktion, eine ganze Zahl zu/von einem pointer), und die Umwandlung von Zeiger aufbool
sind auch alle Konvertierungen angegeben, die Häufig in der Praxis verwendet. Wenn so ein Konstrukt wie deins gab Warnungen, die false positives " wäre riesig, und die Warnung nur selten aktiviert werden. - verwenden Sie nicht
this->
. Das wird vermeiden das problem vollständig double x,y; x == y;
ist auch gültig, aber es ist eine offensichtliche Warnung für diesen Fall.- Nicht mit
this
ist manchmal nicht eine sehr gute option, wie das vererben von templates - Interessant,
-Wpointer-arith
nicht fangen. - Zwei weitere nicht-Echtzeit-Lösungen: wenn Sie ein tool wie Visual Assist, der Fehler ist viel schwieriger zu machen, weil es kann automatisch hinzufügen
->
nach einem Zeiger. Sie können auch Ihre version control pre-commit-hooks zu stoppen Instanzenthis-
ohne>
folgende. - "die meisten Compiler erzeugen Warnungen für "richtige" C++ - Sätze": ich würde so weit gehen zu sagen, dass alle Warnungen werden von "richtigen" C++ - Sätze. Wenn es nicht gültigen code, den Sie bekommen würde, sondern ein Fehler.
- Zeiger-Arithmetik auf
this
sinnvoll sein können, aber umwandeln des Ergebnisses zubool
ist nicht. Clang ist-Wundefined-bool-conversion
warnt impliziten Konvertierung vonthis
zubool
, das ist immer wahr. Es könnte unter Umständen erweitert werden, um auch warnen, auf eine implizite Konvertierung vonthis-n
zubool
, die ist auch immer wahr. - vorausgesetzt, das Objekt ist Teil eines Arrays und den Zugriff auf das vorhergehende, - dann gefeuert 🙂
- Ugh, es sollte nur verboten, eine binäre Subtraktion ohne whitespace um es in den ersten Platz. @LưuVĩnhPhúc: ich weiß, dass das Häufig, aber ich halte es für eine schlechte Praxis. Es zwingt auch Sie, um den Namen der Basisklasse, wenn die Erben (wenn Sie abhängige Typen beteiligt sind), das ist ärgerlich und inkonsequent.
- Sie haben Recht, die
this->
sollten vermieden werden, wo möglich. Es gibt jedoch Fälle, wothis->
erforderlich ist (template-Vererbung), so ist es sollte angemerkt werden, dass die Orte, an denenthis->
ist tatsächlich erforderlich, sind auch die Fälle, in denen eine fehlerhaftethis-b
ist ein Fehler (weilb
ist nicht zugänglich ohne diethis->
). Also die Regel ist: benutzen Sie nichtthis->
es sei denn, erforderlich. - Ich hoffe, dass die Menschen, die sich verschworen, um die Subtraktion ein boolescher Wert von einem Zeiger legal in C++ fühlen Sie sich zumindest ein wenig schuldig. Die Zeiger auf bool-Konvertierung ist nur zu verteidigen, sondern indem Sie die Subtraktion mit bools?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Zu diesem Problem ist erkannt
cppcheck
:War dies ohne include-Pfad gegeben. Wenn ich
-I /usr/include/c++/4.8/
, das Problem ist immer noch erkannt:dann cppcheck langsam arbeitet sich durch die oben genannten
#ifdef
Konfigurationen.(Wie sehen a side note, die Fehler in
local_classes.tcc
ist ein false positive, aber dies ist sehr schwer zu sagen, für ein automatisiertes tool, als würde es brauchen, um bewusst sein, dass diecatch
block auf dieser Website darf nicht eingegeben werden, wenn der makro__EXCEPTIONS
ist nicht gesetzt.)Disclaimer: ich habe keine anderen Erfahrungen mit cppcheck.
Nein,
this - b
ist die Durchführung Zeiger-Arithmetik auf den Zeigerthis
trotzb
einbool
Typ (b
implizit inint
).(Interessanterweise, können Sie immer set
this + b
auf einen Zeiger, wob
ist einbool
geben, da können Sie einen Zeiger auf eine Vergangenheit das Ende einer skalaren! So auch Ihre Lieblings - Undefiniertes Verhalten spotter erlauben würde, dass man.)Überprüfung von Array-Grenzen hat immer schon die Aufgabe ein C++ - Programmierer.
Beachten Sie auch, dass in Ihren Fällen die Verwendung von
this
ist überflüssig: so einzuschränken das übermäßige verwenden, ist ein Weg, das problem Weg.this->
für die Verständlichkeit der Gründe beim Lesen den code. Vielleicht eine schlechte Idee. Aber mit der änderung, dass ist wirklich teuer jetzt.this
?! Das Geld ausgeben und zu beheben. Wohlgemerkt, ich benutzem_
für member-Variablen, unds_
für Statik. Zurück in meine box 😉this->
bieten die Garantie bei der Kompilierung, dass es ein Mitglied. Mitm_
oders_
nicht verhindern, dass gegen eine lokale/Globale variable (leider) nicht unter diesem Namen. Es war der Grund. Aber, natürlich, könnte es interessant sein, zu öffnen, diese Entscheidung. StackOverflow ist nicht die beste Plattform, um zu diskutieren, die Art von Frage, die (glaube ich). Was könnte gut sein ?bool(this-n)
ist immer wahr. Zum Beispiel, klammerten sich bereits emittiert eine Warnung für implizitebool(this)
.b
wahr ist undthis == (A *)(sizeof A)
(das ist eine rechtliche wenn auch unwahrscheinlich Standort für ein Eine auf zu existieren, zumindest auf Plattformen, auf denen die Größe eines Zeigers ist die gleiche wie die Größe dersize_t
, was wahr ist in den meisten Fällen) wird false zurückgegeben./proc/sys/vm/mmap_min_addr
hat seinen default-Wert65536
, und somit keine gültige Adresse innerhalb des Programms kann in der niedrigen 64kiB. Oder zumindest warnen, auf dieser Basis, wenn nicht sogar das optimieren der Weg der Mathematik. (Spaß Tatsache: ein use-case für das ändern des kernel-Einstellung mit Emulatoren/Wrapper (WEIN für 16-bit-binaries von QEMU, von DOSBOX) mit virtuellen Adressraum als Gast physischen Adressen: wiki.debian.org/mmap_min_addr. Scheinbar modernen QEMU und DOSBOX umgehen Sie es jetzt.)m_
unds_
wenn ich ein wee-Zange bei Goldman Sachs. Ich habe auch gesehenmy
als Präfix für Mitglieder undour
als Präfix für Statik. Persönlich, obwohl ich nicht gerne verlassen Sie sich auf syntax-Färbung zu bezeichnen member-Variablen: Es ist ziemlich schwer zu konfigurieren vi zu tun!nullptr
oder ein integer-literal null, und [KONV.bool] sagt, dass alle anderen Zeiger sindtrue
. Der einzige Weg, um ihn in eine situation, in derthis-n
istfalse
ist durch Undefiniertes Verhalten.Möchte ich Ihnen ein weiteres Werkzeug (abgesehen von
cppcheck
vorgeschlagen von @arne-vogel), was eine bessere visuelle Hilfe statt der Warnung gefragt:Verwenden clang-format automatisch formatieren Sie den code. Das Ergebnis könnte wie folgt Aussehen (abhängig von den Einstellungen), damit der Fehler besser sichtbar durch die Räume, die Hinzugefügt, um
operator-
:Nein, es gibt keine Möglichkeit, eine Warnung erhalten. Die impliziten Konvertierungen, obwohl perverse, dürfen von der Sprache.
Aber in diesem bestimmten Fall können wir besser machen - durch einwickeln der bool in einer wrapper-class, die explizite Konvertierungen und keine arithmetischen Operationen definiert.
Dies führt zu einem compiler-Fehler, wenn sich logisch missbraucht, das ist normalerweise vorzuziehen, eine Warnung, wenn die logische Korrektheit ist das Ziel.
Es ist interessant zu beachten, dass c++17 deprecates
bool::operator++
als diese Arithmetik wird als übel angesehen.Beispiel:
std::vector<Bool>
reduzieren von Speicher ? Es ist offensichtlich nicht die Lösung. Ich will nicht zu ändern, eine grundlegende Art in meinem code...std::vector<bool>
. Der main unit verwenden von Arbeitsspeicher der code ist eine Klasse, in der mehrere sehr große Vektoren von booleschen Werten. Es ist leicht viel Speicher gespart, indem Sie von 5Go zu 1Go für eine normale Nutzung.-Wundefined-bool-conversion
im Klang.Bool
? Warum nicht wir auch definierenInt
,Float
,Double
,VolatileUnsignedLongLong
, ..?if (a = f())
produzieren eine Warnung für viele Compiler (wird zum schweigen gebracht durchif ((a = f()))
.g++
gibt eine Warnung für einschränkende Konvertierungen in einigen Fällen, in denen die Sprache, die spec erlaubt es Ihnen.std::vector<bool>
: Eine dynamisch-size-bitmap ist eine nützliche Daten-Struktur, aber es ist bedauerlich, dass C++ wählte, es zu nennenstd::vector<bool>
stattstd::bit_vector
oder so etwas. Das etwas, was ich denke, fast jeder Zustimmen können. Siehe isocpp.org/blog/2012/11/on-vectorbool für einige ausgezeichnete Punkte, vor allem, dass die standard-Bibliothek sollte so ein Typ, mit optimierten Implementierungen fürstd::find
,std::count
, und so weiter, denn das ist eine gute Möglichkeit zur Bereitstellung von Plattform-spezifischen popcnt / bit-scan-Zeug.libc++
hat optimierte Implementierungen von einigenstd::
algorithmen überstd::vector<bool>
, so Rollen Sie Ihre eigenen bit-Vektor nur zu vermeidenvector<bool>
weh tun wird, die Leistung auf einigen C++ - Implementierungen.