Ich habe die Begriffe "IB" und "UB" mehrmals gesehen, insbesondere im Zusammenhang mit C ++. Ich habe versucht, sie zu googeln, aber anscheinend werden diese Zwei-Buchstaben-Kombinationen häufig verwendet. : P.
Also, ich frage dich ... was meinen sie, wenn sie gesagt werden, als wären sie eine schlechte Sache?
c++
terminology
definition
cHao
quelle
quelle
Antworten:
IB: Implementierungsdefiniertes Verhalten. Der Standard überlässt es dem jeweiligen Compiler / der jeweiligen Plattform, das genaue Verhalten zu definieren, verlangt jedoch, dass es definiert wird.
Die Verwendung eines implementierungsdefinierten Verhaltens kann nützlich sein, macht Ihren Code jedoch weniger portabel.
UB: Undefiniertes Verhalten. Der Standard legt nicht fest, wie sich ein Programm, das undefiniertes Verhalten aufruft, verhalten soll. Auch als "Nasendämonen" bekannt, da theoretisch Dämonen aus der Nase fliegen könnten.
Die Verwendung von undefiniertem Verhalten ist fast immer eine schlechte Idee. Selbst wenn es manchmal zu funktionieren scheint, kann jede Änderung an Umgebung, Compiler oder Plattform Ihren Code zufällig beschädigen.
quelle
Implementierungsdefiniertes Verhalten und undefiniertes Verhalten
Der C ++ - Standard ist sehr spezifisch in Bezug auf die Auswirkungen verschiedener Konstrukte, und insbesondere sollten Sie sich immer dieser Kategorien von Problemen bewusst sein :
Undefiniertes Verhalten bedeutet, dass absolut keine Garantien gegeben werden. Der Code könnte funktionieren oder Ihre Festplatte in Brand setzen oder Dämonen aus Ihrer Nase fliegen lassen . In Bezug auf die C ++ - Sprache kann absolut alles passieren. In der Praxis bedeutet dies im Allgemeinen, dass Sie einen nicht behebbaren Fehler haben. Wenn dies geschieht, kann man nicht vertrauen wirklich etwas über Ihre Bewerbung (weil eine der Auswirkungen dieser undefinierten Verhalten könnte nur zu Chaos gewesen Speicher durch den Rest Ihrer App verwendet wird ). Es muss nicht konsistent sein, daher kann das zweimalige Ausführen des Programms zu unterschiedlichen Ergebnissen führen. Dies kann von den Mondphasen, der Farbe des Hemdes, das Sie tragen, oder absolut allem anderen abhängen.
Nicht spezifiziertes Verhalten bedeutet, dass das Programm etwas Vernünftiges und Konsistentes tun muss, dies muss jedoch nicht dokumentiert werden .
Das implementierungsdefinierte Verhalten ähnelt dem nicht angegebenen, muss jedoch auch von den Compiler-Autoren dokumentiert werden. Ein Beispiel hierfür ist das Ergebnis von a
reinterpret_cast
. in der Regel , ändert er einfach den Typ eines Zeigers, ohne die Adresse zu ändern, aber die Abbildung tatsächlich die Implementierung definiert, so dass ein Compiler könnte auf eine ganz andere Adresse zuordnen, solange sie diese Wahl dokumentiert. Ein weiteres Beispiel ist die Größe eines Int. Dem C ++ - Standard ist es egal, ob es 2, 4 oder 8 Bytes sind, aber er muss vom Compiler dokumentiert werdenAllen gemeinsam ist jedoch, dass sie am besten vermieden werden. Halten Sie sich nach Möglichkeit an ein Verhalten, das zu 100% im C ++ - Standard selbst festgelegt ist. Auf diese Weise ist Ihnen die Portabilität garantiert.
Oft müssen Sie sich auch auf ein implementierungsdefiniertes Verhalten verlassen. Es mag unvermeidlich sein, aber Sie sollten trotzdem darauf achten und sich bewusst sein, dass Sie sich auf etwas verlassen, das sich zwischen verschiedenen Compilern ändern kann.
Undefiniertes Verhalten sollte dagegen immer vermieden werden. Im Allgemeinen sollten Sie einfach davon ausgehen, dass Ihr Programm auf die eine oder andere Weise explodiert.
quelle
IB: Ist das implementierungsdefinierte Verhalten - der Compiler muss dokumentieren, was er tut.
>>
Ein Beispiel ist die Ausführung einer Operation mit einem negativen Wert.UB: undefiniertes Verhalten - Der Compiler kann alles tun, einschließlich einfach abstürzen oder unvorhersehbare Ergebnisse liefern. Das Dereferenzieren eines Nullzeigers fällt in diese Kategorie, aber auch subtilere Dinge wie Zeigerarithmetik, die außerhalb der Grenzen eines Arrayobjekts liegen.
Ein anderer verwandter Begriff ist "nicht spezifiziertes Verhalten". Dies ist eine Art zwischen implementierungsdefiniertem und undefiniertem Verhalten. Für nicht spezifiziertes Verhalten muss der Compiler etwas gemäß dem Standard tun, aber genau, welche Auswahl der Standard ihm gibt, liegt beim Compiler und muss nicht definiert (oder sogar konsistent) werden. Dinge wie die Reihenfolge der Bewertung von Unterausdrücken fallen in diese Kategorie. Der Compiler kann diese in beliebiger Reihenfolge ausführen und sie in verschiedenen Builds oder sogar in verschiedenen Läufen desselben Builds unterschiedlich ausführen (unwahrscheinlich, aber zulässig).
quelle
Die Kurzversion:
Implementierungsdefiniertes Verhalten (IB): Richtig programmiert, aber unbestimmt *
Undefiniertes Verhalten (UB): Falsch programmiert (dh ein Fehler !)
*) "unbestimmt", was den Sprachstandard betrifft, wird er natürlich auf jeder festen Plattform bestimmt.
quelle
UB: Undefiniertes Verhalten
IB: Implementierungsdefiniertes Verhalten
quelle