Constant expressions
Plusieurs variétés d'expressions sont connues sous le nom d' expressions constantes .
Table des matières |
Expression constante du préprocesseur
L'expression suivant
#if
ou
#elif
doit s'étendre à
- opérateurs autres que assignation , incrémentation, décrémentation , appel de fonction , ou virgule dont les arguments sont des expressions constantes de préprocesseur
- constantes entières
- constantes de caractère
-
l'opérateur spécial du préprocesseur
defined.
Les constantes de caractères, lorsqu'elles sont évaluées dans des
#if
-expressions, peuvent être interprétées dans le jeu de caractères source,
le jeu de caractères d'exécution, ou un autre jeu de caractères défini par l'implémentation.
|
L'arithmétique entière dans les expressions
|
(depuis C99) |
Expression constante entière
Une expression constante entière est une expression qui se compose uniquement de
- opérateurs autres que assignation , incrémentation, décrémentation , appel de fonction , ou virgule , sauf que les opérateurs de conversion ne peuvent convertir que des types arithmétiques en types entiers, sauf s'ils font partie d'un opérande d'un opérateur sizeof , _Alignof (depuis C11) (jusqu'à C23) , alignas (depuis C23) ou typeof/typeof_unqual (depuis C23) .
- constantes entières
- constantes d'énumération
- constantes de caractère
- constantes flottantes , mais seulement si elles sont immédiatement utilisées comme opérandes de conversions vers un type entier
-
sizeofopérateurs dont les opérandes ne sont pas VLA (depuis C99)
|
(depuis C11) |
|
(depuis C23) |
Les expressions constantes entières sont évaluées à la compilation. Les contextes suivants requièrent des expressions connues sous le nom d' expressions constantes entières :
- La taille d'un bit-field .
- La valeur d'une enumeration constant
-
Le
caselabel d'une switch statement - La taille d'un tableau non-VLA (depuis C99)
- Conversion conversion implicite d'entier vers pointeur.
|
(depuis C99) |
|
(depuis C11) |
|
(depuis C23) |
Initialiseur statique
Les expressions utilisées dans les initialiseurs des objets ayant une durée de stockage statique et thread_local ou déclarés avec le spécificateur de classe de stockage constexpr (depuis C23) doivent être soit des littéraux de chaîne, soit des expressions pouvant être l'une des suivantes
-
- opérateurs autres que assignation , incrémentation, décrémentation , appel de fonction , ou virgule , sauf que les opérateurs de conversion doivent convertir des types arithmétiques vers d'autres types arithmétiques à moins qu'ils ne fassent partie d'un opérande d'un opérateur sizeof , _Alignof (depuis C11) (jusqu'à C23) , alignof (depuis C23) ou typeof/typeof_unqual (depuis C23)
- constantes entières
- constantes flottantes
- constantes d'énumération
- constantes caractère
-
sizeofopérateurs dont les opérandes ne sont pas VLA (depuis C99)
| (depuis C11) |
|
(depuis C23) |
-
- un pointeur nul
- lvalue désignant un objet de durée de stockage statique ou un désignateur de fonction, converti en pointeur soit
-
- en utilisant l'opérateur unaire d'adresse
- en convertissant une constante entière en pointeur
- par conversion implicite tableau-vers-pointeur ou fonction-vers-pointeur conversion .
|
5)
une
constante nommée
qui est, un identifiant qui est
.
à une constante nommée de type structure ou union, même récursivement.
6)
une
constante littérale composée
, qui est
Une
constante de structure ou d'union
est respectivement une constante nommée ou une constante littérale composée de type structure ou union. Si l'opérateur d'accès membre
|
(depuis C23) |
Contrairement aux expressions constantes entières, les expressions d'initialiseur statique ne sont pas tenues d'être évaluées à la compilation ; le compilateur a la liberté de transformer ces initialiseurs en code exécutable qui est invoqué avant le démarrage du programme.
static int i = 2 || 1 / 0; // initialise i à la valeur 1
|
Cette section est incomplète
Motif : autres mini-exemples |
La valeur d'un initialiseur statique de type à virgule flottante n'est jamais moins précise que la valeur de la même expression exécutée à l'exécution, mais elle peut être meilleure.
Expressions constantes à virgule flottante
Les expressions constantes arithmétiques de types à virgule flottante qui ne sont pas utilisées dans des initialiseurs statiques sont toujours évaluées comme si elles l'étaient pendant l'exécution et sont affectées par la méthode d'arrondi courante (si FENV_ACCESS est activé) et signalent les erreurs comme spécifié dans math_errhandling .
void f(void) { #pragma STDC FENV_ACCESS ON static float x = 0.0 / 0.0; // initialiseur statique : ne lève pas d'exception float w[] = { 0.0 / 0.0 }; // lève une exception float y = 0.0 / 0.0; // lève une exception double z = 0.0 / 0.0; // lève une exception }
Notes
Si une expression évalue à une valeur qui n'est pas représentable par son type, elle ne peut pas être utilisée comme expression constante.
Les implémentations peuvent accepter d'autres formes d'expressions constantes. Cependant, ces expressions constantes ne sont pas considérées comme des expressions constantes entières, des expressions constantes arithmétiques ou des expressions constantes d'adresse, et ne peuvent donc pas être utilisées dans les contextes nécessitant ces types d'expressions constantes. Par exemple, int arr [ ( int ) + 1.0 ] ; déclare un VLA.
Références
- Norme C23 (ISO/CEI 9899:2024) :
-
- 6.6 Expressions constantes (p: 95-96)
- Norme C17 (ISO/CEI 9899:2018):
-
- 6.6 Expressions constantes (p: 76-77)
- Norme C11 (ISO/IEC 9899:2011) :
-
- 6.6 Expressions constantes (p: 106-107)
- Norme C99 (ISO/CEI 9899:1999) :
-
- 6.6 Expressions constantes (p: 95-96)
- Norme C89/C90 (ISO/IEC 9899:1990) :
-
- 3.4 EXPRESSIONS CONSTANTES
Voir aussi
|
Documentation C++
pour
Expressions constantes
|