Es ist ein offensichtlicher Fehler, außer Zweifel.
Die Absicht der Warnung ist NICHT, über alle Unterteilungen in einem Programm zu warnen. Das wäre viel zu laut in irgendeinem vernünftigen Programm. Stattdessen besteht die Absicht darin, Sie zu warnen, wenn Sie ein Argument überprüfen müssen. In diesem Fall haben Sie das Argument überprüft. Daher sollte der Compiler dies bemerkt haben und den Mund halten.
Die technische Implementierung eines solchen Features erfolgt durch die Kennzeichnung von Variablen in Code-Zweigen mit bestimmten Attributen. Eines der gebräuchlichsten Attribute ist der Dreizustand "Ist Null". Vor der Verzweigung ist arg
eine externe Variable und arg [[Isnull]]
ist unbekannt. Aber nach der Überprüfung auf arg
gibt es zwei Zweige. Im ersten Zweig ist arg [[Isnull]]
wahr. Im zweiten Zweig ist arg [[Isnull]]
falsch.
Wenn es darum geht, durch Nullzeiger und Nullzeiger Warnungen zu generieren, sollte das Attribut [[IsNull]
überprüft werden. Wenn dies der Fall ist, haben Sie eine schwerwiegende Warnung / einen Fehler. Wenn sie nicht bekannt sind, sollten Sie die oben gezeigte Warnung generieren - ein potenzielles Problem, über das hinaus, was der Compiler beweisen kann. In diesem Fall ist das Attribut [[isNull]]
jedoch False. Der Compiler durch die gleiche formale Logik wie Menschen weiß, dass es kein Risiko gibt.
Aber woher wissen wir, dass der Compiler intern ein solches Attribut [[Isnull]]
verwendet? Erinnern Sie sich an den ersten Absatz: Ohne ihn müsste er entweder immer oder nie warnen. Wir wissen, dass es manchmal warnt, daher muss ein Attribut [[IsNull]]
vorhanden sein.
Der Compiler ist nicht in der Lage, alle Code-Pfade statisch zu analysieren und alle Möglichkeiten jederzeit zu berücksichtigen. Theoretisch kann die vollständige Analyse eines Programmverhaltens, indem man einfach in den Quellcode schaut, eine Lösung für das Anhalten des Problems liefern, die unentscheidbar ist. Compiler haben eine begrenzte Anzahl von statischen Analyse-Regeln, um Regeln zu erkennen. Der C ++ - Standard erfordert nicht, dass der Compiler solche Warnungen ausgibt, also nein. Es ist kein Fehler. Es ist mehr wie eine nicht vorhandene Funktion.
Nein, der bedingte Operator wertet beide Argumente nicht aus. Ein Potential dividiere durch Null, wenn ein Compiler eine solche Sache erkennen kann, wird jedoch typischerweise gemeldet. Es ist nicht umsonst, dass der Standard ~ 2 Seiten benötigt, um das Verhalten dieses Operators zu beschreiben.
Von N-4411:
5.16 Bedingter Operator
1 Gruppe für bedingte Ausdrücke rechts nach links. Der erste Ausdruck ist Kontextuell in Boole umgewandelt 4). Es wird ausgewertet und wenn es wahr ist, das Ergebnis der Bedingung Ausdruck ist der Wert des zweiten Ausdruck, sonst der der dritter Ausdruck. Nur einer der zweiter und dritter Ausdruck ist bewertet. Jede Wertberechnung und Nebeneffekt mit dem ersten verbunden Der Ausdruck ist vor jedem sequenziert Wertberechnung und Nebeneffekt mit dem zweiten oder dritten verbunden Ausdruck.
Beachten Sie auch:
3 Ansonsten, wenn die zweite und dritte Operand haben verschiedene Arten und entweder hat (möglicherweise cv-qualifiziert) Klassentyp, ein Versuch wird gemacht wandle jeden dieser Operanden in den Art des anderen.
Das von Ihnen zitierte Beispiel hat denselben Typ für den zweiten und den dritten Ausdruck - seien Sie versichert, nur der erste wird ausgewertet.
Der Code für die Division wird generiert, daher die Warnung. aber die Verzweigung wird nie genommen, wenn arg
0 ist, also ist es sicher.
operator == für Fließkommazahlen ist unsicher (d. h. Sie können ihm aufgrund von Rundungsproblemen nicht vertrauen). In diesem speziellen Fall ist es tatsächlich sicher, so dass Sie die Warnung ignorieren können, aber der Compiler wird eine solche Analyse nicht basierend auf einem Operator durchführen, dessen Ergebnisse im allgemeinen Fall etwas unvorhersehbar sind.
Der Bedingungsoperator sollte nicht alle Argumente auswerten. Aber ich glaube, du könntest arg
fast gleich 0 nehmen, also wird arg == 0.0
false
sein, aber 1./arg
wird "Division durch Null" ergeben. Also denke ich, dass die Warnung hier nützlich ist.
Übrigens gibt Visual C ++ 2008 keine solche Warnung.
Zusätzlich zu den anderen Kommentaren: Die Warnung wird vom Compiler generiert, der tote Zweig wird vom Optimierer entfernt, der später ausgeführt wird - möglicherweise sogar in der Verknüpfungsphase.
Also nein, es ist kein Fehler. Die Warnung ist ein zusätzlicher Service, der vom Compiler bereitgestellt wird und nicht vom Standard vorgeschrieben wird. Es ist ein unglücklicher Nebeneffekt der Compiler / Linker-Architektur.
Sie können die Warnung möglicherweise mithilfe des Microsoft-spezifischen Schlüsselworts __assume
vermeiden. Ich bin mir nicht sicher, ob Sie es mit dem Bedingungsoperator verknüpfen können. Sonst etwas wie
kann einen Versuch wert sein. Oder, natürlich, stumm die Warnung während dieser Funktion mit der entsprechenden #pragma
.
Tags und Links c++ 64bit visual-studio-2005