Steuerung des implementierungsdefinierten Verhaltens
Implementierungsdefiniertes Verhalten wird durch die Direktive #pragma gesteuert.
Inhalt |
[bearbeiten] Syntax
#pragma pragma-params |
(1) | ||||||||
_Pragma( string-literal ) |
(2) | (seit C++11) | |||||||
L-Präfix (falls vorhanden), die äußeren Anführungszeichen und führende/nachfolgende Leerzeichen aus string-literal, ersetzt jedes \" durch " und jedes \\ durch \, tokenisiert dann das Ergebnis (wie in Übersetzungsphase 3) und verwendet dann das Ergebnis, als ob es die Eingabe für #pragma in (1) wäre.[bearbeiten] Erklärung
Die Pragma-Direktive steuert implementierungsspezifisches Verhalten des Compilers, wie z.B. das Deaktivieren von Compiler-Warnungen oder das Ändern von Ausrichtungsvorgaben. Jedes nicht erkannte Pragma wird ignoriert.
[bearbeiten] Nicht-Standard-Pragmas
Der ISO C++ Sprachstandard schreibt den Compilern keine Unterstützung für bestimmte Pragmas vor. Allerdings werden mehrere nicht-standardmäßige Pragmas von mehreren Implementierungen unterstützt.
[bearbeiten] #pragma STDC
Der ISO C Sprachstandard verlangt, dass C-Compiler die folgenden drei Pragmas unterstützen. Einige C++-Compiler-Anbieter unterstützen sie in ihren C++-Frontends in unterschiedlichem Maße.
#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.
ON gesetzt, informiert es den Compiler, dass das Programm auf die Gleitkomma-Umgebung zugreifen oder diese modifizieren wird. Dies bedeutet, dass Optimierungen, die Flag-Tests und Modusänderungen untergraben könnten (z. B. globale gemeinsame Subausdrucks-Eliminierung, Code-Bewegung und Konstanten-Faltung), verboten sind. Der Standardwert ist implementierungsdefiniert, üblicherweise OFF.ON.+v2
) und |x+iy| = √x2
+y2
, trotz der Möglichkeit von Zwischenüberläufen. Mit anderen Worten, der Programmierer garantiert, dass der Wertebereich der an diese Funktionen übergebenen Werte begrenzt ist. Der Standardwert ist
OFF.Das Verhalten des Programms ist undefiniert, wenn eines der drei oben genannten Pragmas in einem anderen Kontext als außerhalb aller externen Deklarationen oder vor allen expliziten Deklarationen und Anweisungen innerhalb einer zusammengesetzten Anweisung vorkommt.
Hinweis: Compiler, die diese Pragmas nicht unterstützen, bieten möglicherweise gleichwertige Kompilierungsoptionen an, wie z. B. gcc's -fcx-limited-range und -ffp-contract.
[bearbeiten] #pragma once
#pragma once ist ein nicht-standardmäßiges Pragma, das von der überwiegenden Mehrheit moderner Compiler unterstützt wird. Wenn es in einer Header-Datei vorkommt, zeigt es an, dass diese nur einmalig übersetzt werden soll, auch wenn sie mehrmals (direkt oder indirekt) in derselben Quelldatei eingebunden wird.
Der Standardansatz zur Verhinderung der mehrfachen Einbindung derselben Header-Datei ist die Verwendung von Include Guards.
#ifndef LIBRARY_FILENAME_H #define LIBRARY_FILENAME_H // contents of the header #endif /* LIBRARY_FILENAME_H */
So dass alle bis auf die erste Einbindung des Headers in einer beliebigen Translation Unit von der Kompilierung ausgeschlossen werden. Alle modernen Compiler merken sich die Tatsache, dass eine Header-Datei einen Include Guard verwendet, und parsen die Datei nicht erneut, wenn sie wieder angetroffen wird, solange der Guard noch definiert ist (siehe z. B. gcc).
Mit #pragma once erscheint derselbe Header wie
#pragma once // contents of the header
Im Gegensatz zu Header Guards macht dieses Pragma es unmöglich, denselben Makronamen versehentlich in mehr als einer Datei zu verwenden. Andererseits kann es, da bei #pragma once Dateien anhand ihrer Dateisystem-Identität ausgeschlossen werden, nicht vor dem zweimaligen Einbinden eines Headers schützen, wenn dieser an mehreren Orten in einem Projekt existiert.
[bearbeiten] #pragma pack
Diese Pragma-Familie steuert die maximale Ausrichtung für nachfolgend 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.
#pragma pack kann die Ausrichtung einer Klasse verringern, kann jedoch eine Klasse nicht übermäßig ausrichten.
Siehe spezifische Details für GCC und MSVC.
| Dieser Abschnitt ist unvollständig Grund: Erklären Sie die Auswirkungen dieser Pragmas auf Datenmember sowie die Vor- und Nachteile ihrer Verwendung. Quellen als Referenz |
| Dieser Abschnitt ist unvollständig Grund: kein Beispiel |
[bearbeiten] Referenzen
- C++23 Standard (ISO/IEC 14882:2024)
- 15.9 Pragma directive [cpp.pragma]
- C++20 Standard (ISO/IEC 14882:2020)
- 15.9 Pragma directive [cpp.pragma]
- C++17 Standard (ISO/IEC 14882:2017)
- 19.6 Pragma directive [cpp.pragma]
- C++14 Standard (ISO/IEC 14882:2014)
- 16.6 Pragma directive [cpp.pragma]
- C++11 Standard (ISO/IEC 14882:2011)
- 16.6 Pragma directive [cpp.pragma]
- C++98 Standard (ISO/IEC 14882:1998)
- 16.6 Pragma directive [cpp.pragma]
[bearbeiten] Siehe auch
| C-Dokumentation für Steuerung des implementierungsdefinierten Verhaltens
|
[bearbeiten] Externe Links
| 1. | C++ Pragmas in Visual Studio |
| 2. | Von GCC akzeptierte Pragmas |
| 3. | Einzelne Pragma-Beschreibungen und Standard-Pragmas in IBM AIX XL C 16.1 |
| 4. | Anhang B. Pragmas im Sun Studio 11 C++ User's Guide |
| 5. | Intel C++ Compiler Pragmas |
| 6. | Release Notes (einschließlich Pragmas) für HP aCC A.06.25 |