Namespaces
Variants

Implementation defined behavior control

From cppreference.net

Le comportement défini par l'implémentation est contrôlé par la directive #pragma .

Table des matières

Syntaxe

#pragma pragma_params (1)
_Pragma ( string-literal ) (2) (depuis C99)
1) Se comporte de manière définie par l'implémentation (sauf si pragma_params est l'un des pragmas standard indiqués ci-dessous).
2) Supprime le préfixe d'encodage (le cas échéant), les guillemets externes et les espaces blancs de début et de fin de string-literal , remplace chaque \" par " et chaque \\ par \ , puis segmente le résultat (comme dans l'étape de traduction 3 ), et utilise ensuite le résultat comme s'il s'agissait de l'entrée de #pragma dans (1) .

Explication

La directive pragma contrôle le comportement spécifique à l'implémentation du compilateur, comme la désactivation des avertissements du compilateur ou la modification des exigences d'alignement. Tout pragma non reconnu est ignoré.

Pragmas standard

Les trois pragmas suivants sont définis par la norme du langage :

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

arg est soit ON soit OFF soit DEFAULT .

1) Si défini sur ON , informe le compilateur que le programme accédera ou modifiera l' environnement en virgule flottante , ce qui signifie que les optimisations qui pourraient compromettre les tests de drapeaux et les changements de mode (par exemple, l'élimination globale des sous-expressions communes, le déplacement de code et le pliage constant) sont interdites. La valeur par défaut est définie par l'implémentation, généralement OFF .
2) Permet la contraction d'expressions à virgule flottante, c'est-à-dire des optimisations qui omettent les erreurs d'arrondi et les exceptions de virgule flottante qui seraient observées si l'expression était évaluée exactement comme écrite. Par exemple, permet l'implémentation de ( x * y ) + z avec une seule instruction CPU de type fused multiply-add. La valeur par défaut est définie par l'implémentation, généralement ON .
3) Informe le compilateur que la multiplication, la division et la valeur absolue des nombres complexes peuvent utiliser des formules mathématiques simplifiées (x+iy)×(u+iv) = (xu-yv)+i(yu+xv) , (x+iy)/(u+iv) = [(xu+yv)+i(yu-xv)]/(u 2
+v 2
)
, et |x+iy| = x 2
+y 2
, malgré la possibilité de dépassement intermédiaire. En d'autres termes, le programmeur garantit que la plage des valeurs qui seront passées à ces fonctions est limitée. La valeur par défaut est OFF .

Remarque : les compilateurs qui ne prennent pas en charge ces pragmas peuvent fournir des options de compilation équivalentes, telles que -fcx-limited-range et -ffp-contract de gcc.

Pragmas non standard

#pragma once

#pragma once est un pragma non standard qui est pris en charge par la grande majorité des compilateurs modernes . S'il apparaît dans un fichier d'en-tête, cela indique qu'il ne doit être analysé qu'une seule fois, même s'il est inclus (directement ou indirectement) plusieurs fois dans le même fichier source.

L'approche standard pour empêcher l'inclusion multiple du même en-tête consiste à utiliser les gardes d'inclusion :

#ifndef LIBRARY_FILENAME_H
#define LIBRARY_FILENAME_H
// contenu de l'en-tête
#endif /* LIBRARY_FILENAME_H */

Ainsi, toutes les inclusions du fichier d'en-tête dans une unité de traduction, sauf la première, sont exclues de la compilation. Tous les compilateurs modernes enregistrent le fait qu'un fichier d'en-tête utilise une garde d'inclusion et ne réanalysent pas le fichier s'il est rencontré à nouveau, tant que la garde est toujours définie (voir par exemple gcc ).

Avec #pragma once , le même en-tête apparaît comme

#pragma once
// contenu de l'en-tête

Contrairement aux gardes d'en-tête, ce pragma rend impossible l'utilisation erronée du même nom de macro dans plusieurs fichiers. En revanche, puisque avec #pragma once les fichiers sont exclus selon leur identité au niveau du système de fichiers, cela ne peut pas protéger contre l'inclusion double d'un en-tête s'il existe à plusieurs emplacements dans un projet.

#pragma pack

Cette famille de pragmas contrôle l'alignement maximum pour les membres de structures et d'unions définis ultérieurement.

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

arg est une petite puissance de deux et spécifie le nouvel alignement en octets.

1) Définit l'alignement actuel à la valeur arg .
2) Définit l'alignement actuel à la valeur par défaut (spécifiée par une option de ligne de commande).
3) Pousse la valeur de l'alignement actuel sur une pile interne.
4) Empile la valeur de l'alignement courant sur la pile interne puis définit l'alignement courant à la valeur arg .
5) Dépile l'entrée supérieure de la pile interne puis définit (restaure) l'alignement actuel à cette valeur.

#pragma pack peut diminuer l'alignement d'une structure, cependant, il ne peut pas rendre une structure sur-alignée.

Voir aussi les détails spécifiques pour GCC et MSVC .

Références

  • Norme C23 (ISO/CEI 9899:2024) :
  • 6.10.6 Directive pragma (p: TBD)
  • 6.10.9 Opérateur pragma (p: TBD)
  • Norme C17 (ISO/CEI 9899:2018) :
  • 6.10.6 Directive pragma (p. 127)
  • 6.10.9 Opérateur pragma (p. 129)
  • Norme C11 (ISO/CEI 9899:2011) :
  • 6.10.6 Directive pragma (p: 174)
  • 6.10.9 Opérateur pragma (p: 178)
  • Norme C99 (ISO/CEI 9899:1999) :
  • 6.10.6 Directive pragma (p. 159)
  • 6.10.9 Opérateur pragma (p. 161-162)
  • Norme C89/C90 (ISO/IEC 9899:1990) :
  • 3.8.6 Directive pragma

Voir aussi

Documentation C++ pour Contrôle du comportement défini par l'implémentation

Liens externes

1. Pragmas C++ dans Visual Studio
2. Pragmas acceptés par GCC
3. Descriptions individuelles des pragmas et Pragmas standards dans IBM AIX XL C 16.1
4. Annexe B. Pragmas dans le Guide de l'utilisateur C++ Sun Studio 11
5. Pragmas du compilateur Intel C++
6. Pragmas du compilateur HP aCC