C Language
Implementierungsdefiniertes Verhalten
Suche…
Bemerkungen
Überblick
Der C-Standard beschreibt die Sprachsyntax, die von der Standardbibliothek bereitgestellten Funktionen und das Verhalten von konformen C-Prozessoren (grob gesagt Compiler) und konformen C-Programmen. In Bezug auf das Verhalten spezifiziert der Standard größtenteils bestimmte Verhaltensweisen für Programme und Prozessoren. Andererseits haben einige Operationen ein explizites oder implizites undefiniertes Verhalten - solche Operationen sind immer zu vermeiden, da Sie sich auf nichts verlassen können. Dazwischen gibt es verschiedene implementierungsdefinierte Verhaltensweisen. Diese Verhaltensweisen können zwischen C-Prozessoren, Laufzeiten und Standardbibliotheken (gemeinsam Implementierungen ) variieren, sie sind jedoch für jede gegebene Implementierung konsistent und zuverlässig, und konforme Implementierungen dokumentieren ihr Verhalten in jedem dieser Bereiche.
Es ist manchmal vernünftig, dass ein Programm auf implementierungsdefiniertes Verhalten angewiesen ist. Wenn das Programm zum Beispiel ohnehin spezifisch für eine bestimmte Betriebsumgebung ist, ist es unwahrscheinlich, dass es von Problemen der Implementierung abhängig ist, die allgemein auf die allgemeinen Prozessoren für diese Umgebung angewendet werden. Alternativ können Sie Direktive zur bedingten Kompilierung verwenden, um durch die Implementierung definierte Verhaltensweisen auszuwählen, die für die verwendete Implementierung geeignet sind. In jedem Fall ist es wichtig zu wissen, für welche Operationen das Verhalten der Implementierung definiert ist, um sie entweder zu vermeiden oder eine fundierte Entscheidung darüber zu treffen, ob und wie sie verwendet werden sollen.
Der Saldo dieser Anmerkungen bildet eine Liste aller durch die Implementierung definierten Verhaltensweisen und Merkmale, die im C2011-Standard festgelegt sind, mit Verweisen auf den Standard. Viele von ihnen verwenden die Terminologie des Standards . Einige andere sind allgemeiner auf den Kontext des Standards angewiesen, z. B. auf die acht Stufen der Übersetzung von Quellcode in ein Programm oder den Unterschied zwischen gehosteten und freistehenden Implementierungen. Einige, die besonders überraschend oder bemerkenswert sind, werden in fetter Schrift dargestellt. Nicht alle beschriebenen Verhaltensweisen werden von früheren C-Standards unterstützt, im Allgemeinen weisen sie jedoch in allen Versionen des Standards, die sie unterstützen, ein durch die Implementierung definiertes Verhalten auf.
Programme und Prozessoren
Allgemeines
Die Anzahl der Bits in einem Byte ( 3,6 / 3 ). Mindestens
8
kann der Istwert mit dem MakroCHAR_BIT
abgefragt werden.Welche Ausgabenachrichten gelten als "Diagnosemeldungen" ( 3.10 / 1 )
Quellübersetzung
Die Art und Weise, in der physische Quelldatei-Multibyte-Zeichen dem Quellzeichensatz ( 5.1.1.2/1 ) zugeordnet werden.
Ob nicht leere Sequenzen von nicht Newline-Leerzeichen in der Übersetzungsphase 3 durch einzelne Leerzeichen ersetzt werden ( 5.1.1.2/1 )
Das oder die Ausführungssatzzeichen, in die Zeichenliterale und Zeichen in Zeichenfolgekonstanten umgewandelt werden (während der Übersetzungsphase 5), wenn ansonsten kein entsprechendes Zeichen vorhanden ist ( 5.1.1.2/1 ).
Betriebsumgebung
Die Art und Weise, in der die zu sendenden Diagnosemeldungen identifiziert werden ( 5.1.1.3/1 ).
Name und Typ der aufgerufenen Funktion in einer freistehenden Implementierung ( 5.1.2.1/1 ).
Welche Bibliotheksfunktionen stehen in einer freistehenden Implementierung über einen festgelegten Mindestsatz hinaus zur Verfügung ( 5.1.2.1/1 ).
Die Auswirkung der Programmbeendigung in einer freistehenden Umgebung ( 5.1.2.1/2 ).
In einer gehosteten Umgebung alle zulässigen Signaturen für die
main()
Funktion außerint main(int argc, char *arg[])
undint main(void)
( 5.1.2.2.1 / 1 ).Die Art und Weise, in der eine gehostete Implementierung die Zeichenfolgen definiert, auf die das zweite Argument von
main()
( 5.1.2.2.1 / 2 ) verweist .Was ist ein "interaktives Gerät" im Sinne der Abschnitte 5.1.2.3 (Programmausführung) und 7.21.3 (Dateien) ( 5.1.2.3/7 ).
Einschränkungen für Objekte, auf die von Interrupt-Handler-Routinen in einer Optimierungsimplementierung verwiesen wird ( 5.1.2.3/10 ).
In einer freistehenden Implementierung, ob mehrere Ausführungsthreads unterstützt werden ( 5.1.2.4/1 ).
Die Werte der Mitglieder des Ausführungszeichensatzes ( 5.2.1 / 1 ).
Die
char
entsprechen den definierten alphabetischen Escape-Sequenzen ( 5.2.2 / 3 ).Die numerischen Ganzzahl- und Fließkommazahlen und -merkmale ( 5.2.4.2/1 ).
Die Genauigkeit der Fließkomma-Arithmetikoperationen und der Konvertierungen der Standardbibliothek von internen Fließkommadaten in Stringdarstellungen ( 5.2.4.2.2 / 6 ).
Der Wert des Makros
FLT_ROUNDS
, das den Standardrundungsmodus mit Gleitkommazahlen codiert ( 5.2.4.2.2 / 8 ).Rundungsverhalten, das durch unterstützte Werte von
FLT_ROUNDS
mehr als 3 oder weniger als -1 ( 5.2.4.2.2 / 8 ) gekennzeichnet ist.Der Wert des Makros
FLT_EVAL_METHOD
, das das Verhalten der Gleitkomma-Auswertung kennzeichnet ( 5.2.4.2.2 / 9 ).Das Verhalten wird durch unterstützte Werte von
FLT_EVAL_METHOD
weniger als -1 ( 5.2.4.2.2 / 9 ) charakterisiert .Die Werte der Makros
FLT_HAS_SUBNORM
,DBL_HAS_SUBNORM
undLDBL_HAS_SUBNORM
, ob die Standard-Gleitkommaformate Subnormalzahlen unterstützen ( 5.2.4.2.2 / 10 ).
Typen
Das Ergebnis des Versuchs, (indirekt) auf ein Objekt mit Threadspeicherdauer von einem anderen Thread als demjenigen zuzugreifen, dem das Objekt zugeordnet ist ( 6.2.4 / 4 ).
Der Wert eines
char
ein Zeichen außerhalb des Grundausführungssatzes hat , zu denen (zugeordnet 6.2.5 / 3 ).Die unterstützten erweiterten Integer-Typen mit Vorzeichen (falls vorhanden) ( 6.2.5 / 4 ) und alle Erweiterungsschlüsselwörter, mit denen sie identifiziert werden.
Gibt an, ob
char
dieselbe Repräsentation und dasselbe Verhalten wiesigned char
oder alsunsigned char
( 6.2.5 / 15 ). Kann mitCHAR_MIN
abgefragt werden.CHAR_MIN
ist entweder0
oderSCHAR_MIN
wennchar
unsigniert bzw. signiert ist.Anzahl, Reihenfolge und Kodierung von Bytes in den Darstellungen von Objekten , sofern nicht ausdrücklich im Standard ( 6.2.6.1/2 ) angegeben.
Welche der drei erkannten Formen der Ganzzahldarstellung gilt in einer bestimmten Situation und ob bestimmte Bitmuster von Ganzzahlobjekten Trapdarstellungen sind ( 6.2.6.2/2 ).
Die Ausrichtungsanforderung jedes Typs ( 6.2.8 / 1 ).
Ob und in welchen Kontexten erweiterte Ausrichtungen unterstützt werden ( 6.2.8 / 3 ).
Der Satz unterstützter erweiterter Ausrichtungen ( 6.2.8 / 4 ).
Die Ganzzahlkonvertierungsranking aller erweiterten Ganzzahlentypen mit Vorzeichen relativ zueinander ( 6.3.1.1/1 ).
Die Auswirkung der Zuweisung eines Bereichs außerhalb des Bereichs zu einer vorzeichenbehafteten Ganzzahl ( 6.3.1.3/3 ).
Wenn einem Gleitkommaobjekt ein nicht darstellbarer Wert innerhalb des Bereichs zugewiesen wird, wird die Art des im Objekt gespeicherten darstellbaren Werts aus den beiden nächstgelegenen darstellbaren Werten ( 6.3.1.4/2 ; 6.3.1.5/1 ; 6.4.4.2) ausgewählt / 3 ).
Das Ergebnis der Konvertierung einer Ganzzahl in einen Zeigertyp mit Ausnahme von ganzzahligen konstanten Ausdrücken mit dem Wert
0
( 6.3.2.3/5 ).
Quellformular
Die Speicherorte in
#pragma
Direktiven, an denen#pragma
erkannt werden ( 6.4 / 4 ).Die Zeichen, einschließlich Multibyte-Zeichen, mit Ausnahme von Unterstrich, lateinischen Buchstaben ohne Akzent , universelle Zeichennamen und Dezimalstellen, die in Bezeichnern ( 6.4.2.1/1 ) vorkommen können.
Die Anzahl der signifikanten Zeichen in einem Bezeichner ( 6.4.2.1/5 ).
Mit einigen Ausnahmen wird die Art und Weise, in der die Quellzeichen in einer Ganzzahl-Zeichenkonstante auf Ausführungssatzzeichen ( 6.4.4.4/2 ; 6.4.4.4/10 ) abgebildet werden .
Das aktuelle Gebietsschema, das zur Berechnung des Werts einer Wide-Zeichenkonstante verwendet wird, und die meisten anderen Aspekte der Konvertierung für viele dieser Konstanten ( 6.4.4.4/11 ).
Gibt an, ob Wide-String-Literal-Token mit unterschiedlichen Präfixen verkettet werden können, und falls ja, die Behandlung der resultierenden Multibyte-Zeichenfolge ( 6.4.5 / 5 )
Das Gebietsschema, das während der Übersetzungsphase 7 zum Konvertieren von Wide-String-Literalen in Mehrbyte-Zeichenfolgen verwendet wird, und deren Wert, wenn das Ergebnis nicht im Ausführungszeichensatz darstellbar ist ( 6.4.5 / 6 ).
Die Art und Weise, in der Header-Namen Dateinamen zugeordnet werden ( 6.4.7 / 2 ).
Auswertung
Ob und wie Fließkommaausdrücke kontrahiert werden, wenn
FP_CONTRACT
nicht verwendet wird ( 6.5 / 8 ).Die Werte der Ergebnisse der
sizeof
und_Alignof
Operatoren ( 6.5.3.4/5 ).Die Größe des Ergebnistyps der Zeigersubtraktion ( 6.5.6 / 9 ).
Das Ergebnis der Verschiebung einer vorzeichenbehafteten Ganzzahl mit negativem Wert ( 6,5,7 / 5 ) nach rechts .
Laufzeitverhalten
Ob der Typ eines bitfield als deklariert
int
ist der gleiche Typ wieunsigned int
oder alssigned int
( 6.7.2 / 5 ).Welche Arten von Bitfeldern können anders als optional qualifiziertes
_Bool
,signed int
undunsigned int
; ob Bitfelder atomare Typen haben können ( 6.7.2.1/5 ).Aspekte, wie Implementierungen den Speicher für Bitfelder auslegen ( 6.7.2.1/11 ).
Die Ausrichtung von Nicht-Bitfeld-Mitgliedern von Strukturen und Vereinigungen ( 6.7.2.1/14 ).
Der zugrunde liegende Typ für jeden aufgelisteten Typ ( 6.7.2.2/4 ).
Was ist ein "Zugriff" auf ein Objekt vom Typ "
volatile
" ( 6.7.3 / 7 ).Die Wirksamkeit von
inline
Funktionsdeklarationen ( 6.7.4 / 6 ).
Präprozessor
Ob Zeichenkonstanten in Präprozessor-Bedingungen in ganzzahlige Werte konvertiert werden wie in gewöhnlichen Ausdrücken und ob eine Einzelzeichenkonstante einen negativen Wert ( 6.10.1 / 4 ) haben kann.
Die Speicherorte suchten nach Dateien, die in einer
#include
Direktive ( 6.10.2 / 2-3 ) angegeben wurden.Die Art und Weise, in der ein Headername aus den Token einer Multi- Token-
#include
Direktive ( 6.10.2 / 4 ) gebildet wird.Die Grenze für die
#include
Verschachtelung von#include
( 6.10.2 / 6 ).Gibt an, ob ein
\
Zeichen vor dem\
eingefügt wird, um einen universellen Zeichennamen in das Ergebnis des Operators#
des Präprozessors ( 6.10.3.2/2 ) einzufügen .Das Verhalten der
#pragma
Vorverarbeitungsrichtlinie für andere Pragmas alsSTDC
( 6.10.6 / 1 ).Der Wert der Makros
__DATE__
und__TIME__
wenn kein Übersetzungsdatum bzw. -zeit verfügbar ist ( 6.10.8.1/1 ).Die interne Zeichencodierung für
wchar_t
wenn das Makro__STDC_ISO_10646__
nicht definiert ist ( 6.10.8.2/1 ).Die interne Zeichenkodierung für
char32_t
wenn das Makro__STDC_UTF_32__
nicht definiert ist ( 6.10.8.2/1 ).
Standardbibliothek
Allgemeines
- Das Format der Nachrichten, die gesendet werden, wenn Assertions fehlschlagen ( 7.2.1.1/2 ).
Gleitkomma-Umgebungsfunktionen
Alle zusätzlichen Fließkomma-Ausnahmen, die über die im Standard definierten ( 7.6 / 6 ) hinausgehen.
Alle zusätzlichen Gleitkomma-Rundungsmodi, die über die vom Standard definierten Werte ( 7.6 / 8 ) hinausgehen.
Alle zusätzlichen Gleitkomma-Umgebungen, die über die vom Standard definierten ( 7.6 / 10 ) hinausgehen.
Der Standardwert des Zugriffsschalters für die Gleitkommaumgebung ( 7.6.1 / 2 ).
Die mit
fegetexceptflag()
( 7.6.2.2/1 ) aufgezeichnete Darstellung der Gleitkommazustandsflags.feraiseexcept()
ob die Funktionferaiseexcept()
zusätzlich die Gleitkommaausnahme "ungenau"feraiseexcept()
wenn sie die Gleitkommaausnahme "Überlauf" oder "Unterlauf" ( 7.6.2.3/2 ) auslöst .
Gebietsschema-bezogene Funktionen
- Die anderen
setlocale()
als"C"
vonsetlocale()
( 7.11.1.1/3 ) unterstützt.
Mathematische Funktionen
Die durch
float_t
unddouble_t
float_t
double_t
wenn das MakroFLT_EVAL_METHOD
einen anderen Wert als0
,1
und2
( 7.12 / 2 ) hat.Alle unterstützten Fließkomma-Klassifizierungen, die über die vom Standard definierten Werte ( 7.12 / 6 ) hinausgehen.
Der von
math.h
zurückgegebene Wert im Falle eines Domänenfehlers ( 7.12.1 / 2 ).Der von
math.h
zurückgegebene Wert funktioniert bei einem Polfehler ( 7.12.1 / 3 ).Der von
math.h
zurückgegebene Wert funktioniert, wenn das Ergebnismath.h
, und Aspekte, oberrno
aufERANGE
und ob unter diesen Umständen eine Gleitkommaausnahmeerrno
wird ( 7.12.1 / 6 ).Der Standardwert des FP-Kontraktionsschalters ( 7.12.2 / 2 ).
fmod()
ob diefmod()
Funktionen 0 zurückgeben oder einen Domänenfehler auslösen, wenn das zweite Argument 0 ( 7.12.10.1/3 ) ist.Gibt an, ob die
remainder()
Funktionen 0 zurückgeben oder einen Domänenfehler auslösen, wenn das zweite Argument 0 ( 7.12.10.2/3 ) ist.Die Anzahl der signifikanten Bits in den Quotientenmodulen, die von den Funktionen
remquo()
( 7.12.10.3/2 ) berechnet werden.remquo()
ob dieremquo()
Funktionen 0 zurückgeben oder einen Domänenfehler auslösen, wenn das zweite Argument 0 ( 7.12.10.3/3 ) ist.
Signale
Der vollständige Satz unterstützter Signale, ihre Semantik und ihre Standardbehandlung ( 7.14 / 4 ).
Wenn ein Signal ausgelöst wird und ein benutzerdefinierter Handler mit diesem Signal verbunden ist, werden die Signale, sofern vorhanden, für die Dauer der Ausführung des Handlers gesperrt ( 7.14.1.1/3 ).
Welche anderen Signale als
SIGFPE
,SIGILL
undSIGSEGV
bewirken, dass das Verhalten bei der Rückkehr von einem benutzerdefinierten Signalhandler undefiniert ist ( 7.14.1.1/3 ).Welche Signale sind anfangs so konfiguriert, dass sie ignoriert werden (unabhängig von ihrer Standardbehandlung; 7.14.1.1/6 ).
Verschiedenes
- Die spezifische Nullzeigerkonstante, auf die sich das Makro
NULL
erweitert ( 7.19 / 3 ).
Dateibehandlungsfunktionen
Gibt an, ob die letzte Zeile eines Textstroms eine abschließende neue Zeile erfordert ( 7.21.2 / 2 ).
Die Anzahl der Nullzeichen, die automatisch an einen Binärstrom angehängt werden ( 7.21.2 / 3 ).
Die Anfangsposition einer Datei, die im Anfügemodus ( 7.21.3 / 1 ) geöffnet wurde.
Gibt an, ob beim Schreiben in einen Textstream der Stream abgeschnitten wird ( 7.21.3 / 2 ).
Unterstützung für Stream-Pufferung ( 7.21.3 / 3 ).
Gibt an, ob Dateien mit der Länge Null vorhanden sind ( 7.21.3 / 4 ).
Die Regeln für das Erstellen gültiger Dateinamen ( 7.21.3 / 8 ).
Ob dieselbe Datei gleichzeitig mehrmals geöffnet werden kann ( 7.21.3 / 8 ).
Art und Wahl der Kodierung für Multibyte-Zeichen ( 7.21.3 / 10 ).
Das Verhalten der Funktion
remove()
, wenn die Zieldatei geöffnet ist ( 7.21.4.1/2 ).Das Verhalten der Funktion rename
rename()
, wenn die Zieldatei bereits vorhanden ist ( 7.21.4.2/2 ).tmpfile()
ob Dateien, die mit der Funktiontmpfile()
, entfernt werden, falls das Programm abnormal beendet wird ( 7.21.4.3/2 ).Welcher Modus unter welchen Umständen wechselt, ist über
freopen()
( 7.21.5.4/3 ) zulässig.
E / A-Funktionen
Welche der zulässigen Darstellungen von unendlichen und nicht-nummerierten FP-Werten von den Funktionen der printf () - Familie erzeugt werden ( 7.21.6.1/8 ).
Die Art und Weise, in der Zeiger von den Funktionen der
printf()
-Familie ( 7.21.6.1/8 ) formatiert werden.Das Verhalten der
scanf()
-Familie funktioniert, wenn das Zeichen-
an einer internen Position der Scanliste eines[
-Felds ( 7.21.6.2/12 ) erscheint.Die meisten Aspekte der Übergabe von
p
Feldern in denscanf()
-Familienfunktionen ( 7.21.6.2/12 ).Der von
fgetpos()
bei einem Fehler festgelegteerrno
Wert ( 7.21.9.1/2 ).Der von
fsetpos()
bei einem Fehlererrno
Wert ( 7.21.9.3/2 ).Der von
ftell()
bei einem Fehlererrno
Wert ( 7.21.9.4/3 ).Die Bedeutung der
strtod()
-Familienfunktionen einiger unterstützter Aspekte einer NaN-Formatierung ( 7.22.1.3p4 ).strtod()
ob diestrtod()
-Familie-Funktionenerrno
aufERANGE
wenn das Ergebnis unterläuft ( 7.22.1.3/10 ).
Speicherbelegungsfunktionen
- Das Verhalten der Speicherzuordnung funktioniert, wenn die Anzahl der angeforderten Bytes 0 ist ( 7.22.3 / 1 ).
Systemumgebungsfunktionen
Welche Bereinigungen werden durchgeführt und welcher Status wird an das Hostbetriebssystem zurückgegeben, wenn die Funktion
abort()
aufgerufen wird ( 7.22.4.1/2 ).Welcher Status wird an die Hostumgebung zurückgegeben, wenn
exit()
aufgerufen wird ( 7.22.4.4/5 ).Die Behandlung offener Streams und welcher Status wird an die
_Exit()
zurückgegeben, wenn_Exit()
aufgerufen wird ( 7.22.4.5/2 ).Die über
getenv()
zugänglichen Umgebungsnamen und die Methode zum Ändern der Umgebung ( 7.22.4.6/2 ).Der Rückgabewert der Funktion
system()
( 7.22.4.8/3 ).
Datums- und Zeitfunktionen
Die lokale Zeitzone und die Sommerzeit ( 7.27.1 / 1 ).
Der Bereich und die Genauigkeit der Zeiten können mit den Typen
clock_t
undtime_t
( 7.27.1 / 4 ) dargestellt werden.Der Beginn der Ära, der als Referenz für die von der Funktion
clock()
Zeiten ( 7.27.2.1/3 ) dient.Der Beginn der Epoche, die als Referenz für die von der Funktion
timespec_get()
Zeiten dient (wenn die ZeitbasisTIME_UTC
; 7.27.2.5/3 ).Die
strftime()
für den%Z
Konvertierungsspezifizierer in der Ländereinstellung "C" ( 7.27.3.5/7 ).
Wide-Character-E / A-Funktionen
Welche der zulässigen Darstellungen von unendlichen und nicht-nummerierten FP-Werten von den Funktionen der
wprintf()
erzeugt werden ( 7.29.2.1/8 ).Die Art und Weise, in der Zeiger von den Funktionen der
wprintf()
-Familie ( 7.29.2.1/8 ) formatiert werden.Das Verhalten der
wscanf()
-Familie funktioniert, wenn das Zeichen-
an einer internen Position der Scanliste eines[
-Feldes ( 7.29.2.2/12 ) erscheint.Die meisten Aspekte der
wscanf()
-Familie behandelnp
Felder ( 7.29.2.2/12 ).Die Bedeutung der
wstrtod()
-Familie einiger unterstützter Aspekte der NaN-Formatierung ( 7.29.4.1.1 / 4 ).wstrtod()
ob diewstrtod()
-Familienfunktionenerrno
aufERANGE
wenn das Ergebnis untergeht ( 7.29.4.1.1 / 10 )
Rechtsverschiebung einer negativen Ganzzahl
int signed_integer = -1;
// The right shift operation exhibits implementation-defined behavior:
int result = signed_integer >> 1;
Einer Ganzzahl einen Wert außerhalb des Bereichs zuweisen
// Supposing SCHAR_MAX, the maximum value that can be represented by a signed char, is
// 127, the behavior of this assignment is implementation-defined:
signed char integer;
integer = 128;
Zuweisung von null Bytes
// The allocation functions have implementation-defined behavior when the requested size
// of the allocation is zero.
void *p = malloc(0);
Darstellung von signierten ganzen Zahlen
Jeder vorzeichenbehaftete ganzzahlige Typ kann in einem von drei Formaten dargestellt werden; Es ist implementierungsdefiniert, welche verwendet wird. Die für jeden gegebenen Integer-Typ mit Vorzeichen verwendete Implementierung, die mindestens so breit wie int
ist, kann zur Laufzeit aus den zwei niedrigstwertigen Bits der Repräsentation von Wert -1
in diesem Typ bestimmt werden:
enum { sign_magnitude = 1, ones_compl = 2, twos_compl = 3, };
#define SIGN_REP(T) ((T)-1 & (T)3)
switch (SIGN_REP(long)) {
case sign_magnitude: { /* do something */ break; }
case ones_compl: { /* do otherwise */ break; }
case twos_compl: { /* do yet else */ break; }
case 0: { _Static_assert(SIGN_REP(long), "bogus sign representation"); }
}
Dasselbe Muster gilt für die Darstellung engerer Typen, sie können jedoch mit dieser Technik nicht getestet werden, da die Operanden von &
vor den Berechnungen "den üblichen arithmetischen Konvertierungen" unterliegen.