Namespaces
Variants

Implementation defined behavior control

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

Implementation defined behavior wird gesteuert durch die #pragma Direktive.

Inhaltsverzeichnis

Syntax

#pragma pragma-params (1)
_Pragma( string-literal ) (2) (seit C++11)
1) Verhält sich auf implementationsdefinierte Weise.
2) Entfernt das L -Präfix (falls vorhanden), die äußeren Anführungszeichen und führende/abschließende Leerzeichen von string-literal , ersetzt jedes \ " durch " und jedes \\ durch \ , tokenisiert dann das Ergebnis (wie in Übersetzungsphase 3 ) und verwendet das Ergebnis dann als wäre es die Eingabe für #pragma in (1) .

Erklärung

Die Pragma-Direktive steuert implementierungsspezifisches Verhalten des Compilers, wie das Deaktivieren von Compiler-Warnungen oder das Ändern von Ausrichtungsanforderungen. Jedes nicht erkannte Pragma wird ignoriert.

Nicht standardkonforme Pragmas

Der ISO C++-Sprachstandard verlangt nicht, dass Compiler irgendwelche Pragma-Anweisungen unterstützen. Allerdings werden mehrere nicht-standardisierte Pragmas von verschiedenen Implementierungen unterstützt:

#pragma STDC

Der ISO-C-Sprachstandard verlangt, dass C-Compiler die folgenden drei Pragmas unterstützen, und einige C++-Compilerhersteller unterstützen diese in unterschiedlichem Maße in ihren C++-Frontends:

#pragma STDC FENV_ACCESS arg (1)
#pragma STDC FP_CONTRACT arg (2)
#pragma STDC CX_LIMITED_RANGE arg (3)

wobei arg entweder ON , OFF oder DEFAULT ist.

1) Wenn auf ON gesetzt, informiert dies den Compiler, dass das Programm auf die Gleitkommaumgebung zugreifen oder sie ändern wird, was bedeutet, dass Optimierungen, die Flag-Tests und Modusänderungen untergraben könnten (z.B. globale Common Subexpression Elimination, Code Motion und Constant Folding), untersagt sind. Der Standardwert ist implementierungsdefiniert, in der Regel OFF .
2) Erlaubt die Kontraktion von Gleitkommaausdrücken, also Optimierungen, die Rundungsfehler und Gleitkommaausnahmen auslassen, die beobachtet würden, wenn der Ausdruck exakt wie geschrieben ausgewertet würde. Erlaubt beispielsweise die Implementierung von ( x * y ) + z mit einer einzelnen fused multiply-add CPU-Instruktion. Der Standardwert ist implementierungsdefiniert, üblicherweise ON .
3) Informiert den Compiler, dass Multiplikation, Division und Absolutbetrag von komplexen Zahlen vereinfachte mathematische Formeln verwenden dürfen (x+iy)×(u+iv) = (xu-yv)+i(yu+xv) , (x+iy)/(u+iv) = [(xu+yv)+i(yu-xv)]/(u 2
+v 2
)
, und |x+iy| = x 2
+y 2
, trotz der Möglichkeit von Zwischenüberläufen. Mit anderen Worten garantiert der Programmierer, dass der Wertebereich der an diese Funktionen übergebenen Werte begrenzt ist. Der Standardwert ist OFF .

Das Verhalten des Programms ist undefiniert, falls eine der drei oben genannten Pragmas in einem anderen Kontext als außerhalb aller externen Deklarationen oder vor allen expliziten Deklarationen und Anweisungen innerhalb eines zusammengesetzten Anweisungsblocks erscheint.

Hinweis: Compiler, die diese Pragmas nicht unterstützen, können äquivalente Kompilierzeitoptionen bereitstellen, wie z.B. gccs -fcx-limited-range und -ffp-contract .

#pragma once

#pragma once ist ein nicht-standardisiertes Pragma, das von der überwiegenden Mehrheit moderner Compiler unterstützt wird. Wenn es in einer Header-Datei erscheint, zeigt es an, dass sie nur einmal geparst werden soll, selbst wenn sie (direkt oder indirekt) mehrmals in derselben Quelldatei eingebunden wird.

Standardmethode zur Vermeidung mehrfacher Einbindung derselben Header-Datei ist die Verwendung von Include Guards :

#ifndef LIBRARY_FILENAME_H
#define LIBRARY_FILENAME_H
// Inhalt der Header-Datei
#endif /* LIBRARY_FILENAME_H */

Damit alle bis auf die erste Einbindung der Header-Datei in jeder Übersetzungseinheit von der Kompilierung ausgeschlossen werden. Alle modernen Compiler merken sich, dass eine Header-Datei einen Include-Guard verwendet und parsen die Datei nicht erneut, wenn sie erneut auftaucht, solange der Guard noch definiert ist (siehe z.B. gcc ).

Mit #pragma once erscheint derselbe Header als

#pragma once
// Inhalt der Header-Datei

Im Gegensatz zu Header-Guards macht dieses Pragma es unmöglich, fälschlicherweise denselben Makronamen in mehr als einer Datei zu verwenden. Andererseits, da mit #pragma once Dateien basierend auf ihrer Dateisystem-Identität ausgeschlossen werden, kann dies nicht davor schützen, einen Header zweimal einzubinden, wenn er an mehr als einer Stelle in einem Projekt existiert.

#pragma pack

Diese Familie von Pragmas steuert die maximale Ausrichtung für anschließend definierte Klassen- und Union-Mitglieder.

#pragma pack( arg ) (1)
#pragma pack() (2)
#pragma pack(push) (3)
#pragma pack(push, arg ) (4)
#pragma pack(pop) (5)

wobei arg eine kleine Zweierpotenz ist und die neue Ausrichtung in Bytes angibt.

1) Setzt die aktuelle Ausrichtung auf den Wert arg .
2) Setzt die aktuelle Ausrichtung auf den Standardwert (angegeben durch eine Kommandozeilenoption).
3) Legt den Wert der aktuellen Ausrichtung auf einen internen Stapel.
4) Legt den Wert der aktuellen Ausrichtung auf dem internen Stapel ab und setzt dann die aktuelle Ausrichtung auf den Wert arg .
5) Entfernt den obersten Eintrag vom internen Stack und setzt (stellt) dann die aktuelle Ausrichtung auf diesen Wert zurück.

#pragma pack kann die Ausrichtung einer Klasse verringern, jedoch kann es eine Klasse nicht überausrichten.

Siehe auch spezifische Details für GCC und MSVC .

Referenzen

  • C++23-Standard (ISO/IEC 14882:2024):
  • 15.9 Pragma-Direktive [cpp.pragma]
  • C++20-Standard (ISO/IEC 14882:2020):
  • 15.9 Pragma-Direktive [cpp.pragma]
  • C++17-Standard (ISO/IEC 14882:2017):
  • 19.6 Pragma-Direktive [cpp.pragma]
  • C++14-Standard (ISO/IEC 14882:2014):
  • 16.6 Pragma-Direktive [cpp.pragma]
  • C++11 Standard (ISO/IEC 14882:2011):
  • 16.6 Pragma-Direktive [cpp.pragma]
  • C++98-Standard (ISO/IEC 14882:1998):
  • 16.6 Pragma-Direktive [cpp.pragma]

Siehe auch

C-Dokumentation für Implementierungsdefiniertes Verhalten Steuerung

Externe Links

1. C++-Pragmas in Visual Studio
2. Pragmas von GCC unterstützt
3. Einzelne Pragmabeschreibungen und Standard-Pragmas in IBM AIX XL C 16.1
4. Anhang B. Pragmas im Sun Studio 11 C++ Benutzerhandbuch
5. Intel C++ Compiler-Pragmas
6. Release-Knoten (enthält Pragmas) für HP aCC A.06.25