Was sind all die gängigen undefinierten Verhaltensweisen, über die ein C ++ - Programmierer Bescheid wissen sollte?
Sagen Sie, wie:
a[i] = i++;
c++
undefined
undefined-behavior
c++-faq
yesraaj
quelle
quelle
Antworten:
Zeiger
NULL
Zeigersmemcpy
zum Kopieren überlappender Puffer .Puffer läuft über
Ganzzahlige Überläufe
int64_t i = 1; i <<= 72
ist undefiniert)Typen, Besetzung und Konst
int i; i++; cout << i;
)volatile
odersig_atomic_t
beim Empfang eines SignalsFunktion und Vorlage
OOP
Quelldatei und Vorverarbeitung
long int
#if
AusdruckZu klassifizieren
quelle
Die Reihenfolge, in der Funktionsparameter ausgewertet werden, ist ein nicht angegebenes Verhalten . (Dadurch wird Ihr Programm nicht abstürzen, explodieren oder Pizza bestellen ... im Gegensatz zu undefiniertem Verhalten .)
Die einzige Voraussetzung ist, dass alle Parameter vollständig ausgewertet werden müssen, bevor die Funktion aufgerufen wird.
Dies:
Kann gleichbedeutend sein mit:
Oder dieses:
Es kann entweder sein; Es liegt am Compiler. Das Ergebnis kann abhängig von den Nebenwirkungen von Bedeutung sein.
quelle
Dem Compiler steht es frei, die Bewertungsteile eines Ausdrucks neu zu ordnen (vorausgesetzt, die Bedeutung bleibt unverändert).
Aus der ursprünglichen Frage:
Double Checked Locking. Und ein leichter Fehler zu machen.
quelle
Mein Favorit ist "Unendliche Rekursion bei der Instanziierung von Vorlagen", da ich glaube, dass dies die einzige ist, bei der das undefinierte Verhalten zur Kompilierungszeit auftritt.
quelle
Zuweisen einer Konstante nach dem Abisolieren
const
mitconst_cast<>
:quelle
Neben undefiniertem Verhalten gibt es auch das ebenso unangenehme implementierungsdefinierte Verhalten .
Undefiniertes Verhalten tritt auf, wenn ein Programm etwas tut, dessen Ergebnis nicht vom Standard angegeben wird.
Implementierungsdefiniertes Verhalten ist eine Aktion eines Programms, deren Ergebnis nicht durch den Standard definiert ist, die die Implementierung jedoch dokumentieren muss. Ein Beispiel ist "Multibyte-Zeichenliterale" aus der Frage "Stapelüberlauf". Gibt es einen C-Compiler, der dies nicht kompilieren kann? .
Implementierungsdefiniertes Verhalten beißt Sie nur, wenn Sie mit der Portierung beginnen (aber ein Upgrade auf eine neue Version des Compilers ist auch eine Portierung!)
quelle
Variablen dürfen in einem Ausdruck nur einmal aktualisiert werden (technisch einmal zwischen Sequenzpunkten).
quelle
Ein grundlegendes Verständnis der verschiedenen Umweltgrenzen. Die vollständige Liste finden Sie in Abschnitt 5.2.4.1 der C-Spezifikation. Hier sind ein paar;
Ich war tatsächlich ein bisschen überrascht über das Limit von 1023 Fallbezeichnungen für eine switch-Anweisung. Ich kann davon ausgehen, dass diese für generierten Code / Lex / Parser ziemlich einfach überschritten werden.
Wenn diese Grenzwerte überschritten werden, haben Sie ein undefiniertes Verhalten (Abstürze, Sicherheitslücken usw.).
Richtig, ich weiß, dass dies aus der C-Spezifikation stammt, aber C ++ teilt diese grundlegenden Unterstützungen.
quelle
Verwenden
memcpy
zum Kopieren zwischen überlappenden Speicherbereichen. Beispielsweise:Das Verhalten ist gemäß dem C-Standard, der vom C ++ 03-Standard subsumiert wird, undefiniert.
7.21.2.1 Die memcpy-Funktion
7.21.2.2 Die memmove-Funktion
quelle
Der einzige Typ, für den C ++ eine Größe garantiert, ist
char
. Und die Größe ist 1. Die Größe aller anderen Typen ist plattformabhängig.quelle
Objekte auf Namespace-Ebene in verschiedenen Kompilierungseinheiten sollten für die Initialisierung niemals voneinander abhängig sein, da ihre Initialisierungsreihenfolge undefiniert ist.
quelle