Expressions
Une expression est une séquence d' opérateurs et de leurs opérandes , qui spécifie un calcul.
L'évaluation d'expression peut produire un résultat (par exemple, l'évaluation de 2 + 2 produit le résultat 4 ) et peut générer des effets secondaires (par exemple, l'évaluation de std:: printf ( "%d" , 4 ) imprime le caractère '4' sur la sortie standard).
Chaque expression en C++ est caractérisée par deux propriétés indépendantes : un type et une catégorie de valeur.
Table des matières |
Général
- catégories de valeurs (lvalue, rvalue , glvalue, prvalue, xvalue (depuis C++11) ) classifient les expressions selon leurs valeurs
- ordre d'évaluation des arguments et sous-expressions spécifie l'ordre dans lequel les résultats intermédiaires sont obtenus
Opérateurs
| Opérateurs courants | ||||||
|---|---|---|---|---|---|---|
| affectation |
incrémentation
décrémentation |
arithmétique | logique | comparaison |
accès
membre |
autres |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
...
]
|
appel de fonction
a ( ... ) |
|
virgule
a, b |
||||||
|
conditionnel
a ? b : c |
||||||
| Opérateurs spéciaux | ||||||
|
static_cast
convertit un type en un autre type apparenté
|
||||||
- précédence des opérateurs définit l'ordre dans lequel les opérateurs sont liés à leurs arguments
- représentations alternatives sont des orthographes alternatives pour certains opérateurs
- surcharge des opérateurs permet de spécifier le comportement des opérateurs avec des classes définies par l'utilisateur.
Conversions
- conversions standard conversions implicites d'un type à un autre
-
const_castconversion -
static_castconversion -
dynamic_castconversion -
reinterpret_castconversion - cast explicite conversion utilisant la notation de cast style C et la notation fonctionnelle
- conversion définie par l'utilisateur permet de spécifier la conversion depuis des classes définies par l'utilisateur
Allocation de mémoire
- expression new alloue de la mémoire dynamiquement
- expression delete libère de la mémoire dynamiquement
Autre
- expressions constantes peuvent être évaluées à la compilation et utilisées dans un contexte de compilation (arguments de template, tailles de tableau, etc.)
-
sizeof -
alignof -
typeid - expression throw
Expressions primaires
Les opérandes de tout opérateur peuvent être d'autres expressions ou des expressions primaires (par exemple, dans 1 + 2 * 3 , les opérandes de l'opérateur+ sont la sous-expression 2 * 3 et l'expression primaire 1 ).
Les expressions primaires sont l'une des suivantes :
-
this - littéraux (par ex. 2 ou "Hello, world" )
-
expressions d'identificateur, incluant
- identificateurs non qualifiés correctement déclarés (par ex. n ou cout ),
- identificateurs qualifiés correctement déclarés (par ex. std::string::npos ), et
- identificateurs à déclarer dans les déclarateurs
| (depuis C++26) |
| (depuis C++11) | |
| (depuis C++17) | |
| (depuis C++20) |
Toute expression entre parenthèses est également classée comme expression primaire : cela garantit que les parenthèses ont une priorité supérieure à tout opérateur. Les parenthèses préservent la valeur, le type et la catégorie de valeur.
Littéraux
Les littéraux sont les jetons d'un programme C++ qui représentent des valeurs constantes intégrées dans le code source.
- littéraux entiers sont des nombres décimaux, octaux, hexadécimaux ou binaires de type entier.
- littéraux de caractères sont des caractères individuels de type
-
- char ou wchar_t
|
(depuis C++11) |
|
(depuis C++20) |
- littéraux à virgule flottante sont des valeurs de type float , double , ou long double
- littéraux de chaîne sont des séquences de caractères de type
-
- const char [ ] ou const wchar_t [ ]
|
(depuis C++11) |
|
(depuis C++20) |
- littéraux booléens sont des valeurs de type bool , c'est-à-dire true et false
|
(depuis C++11) |
Expressions complètes
Une expression constituante est définie comme suit :
- L'expression constituante d'une expression est cette expression.
- Les expressions constituantes d'une liste d'initialisation entre accolades ou d'une liste d'expressions (éventuellement entre parenthèses) sont les expressions constituantes des éléments de la liste respective.
-
Les expressions constituantes d'un
initialiseur
qui commence par
=sont les expressions constituantes de la initializer-clause .
int num1 = 0; num1 += 1; // Cas 1 : l'expression constituante de « num += 1 » est « num += 1 » int arr2[2] = {2, 22} // Cas 2 : les expressions constituantes // de « {2, 22} » sont « 2 » et « 22 » // Cas 3 : les expressions constituantes de « = {2, 22} » // sont les expressions constituantes de « {2, 22} » // (c'est-à-dire également « 2 » et « 22 »)
Les sous-expressions immédiates d'une expression E sont
- les expressions constitutives des E opérandes,
|
(depuis C++14) |
|
(depuis C++11) |
- tout appel de fonction qui E invoque implicitement, ou
- si E est un appel de fonction ou invoque implicitement une fonction, les expressions constitutives de chaque argument par défaut utilisé dans l'appel.
Un sous-expression d'une expression E est un sous-expression immédiat de E ou un sous-expression d'un sous-expression immédiat de E . Notez que les expressions apparaissant dans le « corps de fonction » des expressions lambda ne sont pas des sous-expressions de l'expression lambda. (depuis C++11)
Les expressions suivantes sont des expressions complètes :
| (depuis C++20) |
- déclarateurs des déclarations simples ou des initialiseurs de membres , incluant les expressions constitutives des initialiseurs
- appels des destructeurs générés à la fin de la durée de vie des objets autres que les objets temporaires dont la durée de vie n'a pas été prolongée
|
(depuis C++26) |
- expressions qui ne sont pas une sous-expression d'une autre expression et qui ne font pas partie d'une expression complète
Si une construction de langage est définie pour produire un appel implicite d'une fonction, l'utilisation de cette construction de langage est considérée comme une expression aux fins de cette définition. Les conversions appliquées au résultat d'une expression pour satisfaire aux exigences de la construction de langage dans laquelle l'expression apparaît sont également considérées comme faisant partie de l'expression complète.
Pour un initialiseur, l'exécution de l'initialisation de l'entité (y compris l'évaluation des initialiseurs par défaut des membres d'un agrégat) (depuis C++14) est également considérée comme faisant partie de l'expression complète.
Expressions potentiellement évaluées
|
Une expression est potentiellement évaluée sauf si
|
(jusqu'en C++11) | ||
|
Les opérandes suivants sont des opérandes non évalués , ils ne sont pas évalués :
Une expression est potentiellement évaluée sauf si
|
(depuis C++11) |
Les expressions potentiellement évaluées sont ODR-use .
|
Cette section est incomplète
Motif : exemple d'opérandes non évalués |
Expressions de valeur ignorée
Une expression à valeur ignorée est une expression utilisée uniquement pour ses effets secondaires. La valeur calculée à partir de cette expression est ignorée. De telles expressions incluent l'expression complète de toute instruction d'expression , l'opérande gauche de l'opérateur virgule intégré, ou l'opérande d'une expression de cast qui convertit vers le type void .
Les conversions de tableau en pointeur et de fonction en pointeur ne sont jamais appliquées à la valeur calculée par une expression à valeur ignorée. La conversion de lvalue en rvalue est appliquée si et seulement si l'expression est une glvalue qualifiée volatile et a l'une des formes suivantes (signification intégrée requise, éventuellement entre parenthèses) :
- expression d'identifiant,
- expression d'indice de tableau,
- expression d'accès au membre de classe,
- indirection,
- opération pointeur-vers-membre,
- expression conditionnelle où les deuxième et troisième opérandes sont l'une de ces expressions,
- expression virgule où l'opérande droit est l'une de ces expressions.
De plus, si la lvalue est de type classe qualifié volatile, un constructeur de copie volatile est requis pour initialiser la temporaire rvalue résultante.
|
Si l'expression est une prvalue non-void (après toute conversion lvalue-à-rvalue qui aurait pu avoir lieu), la matérialisation temporaire se produit.
Les compilateurs peuvent émettre des avertissements lorsqu'une expression autre qu'un cast vers
void
ignore une valeur déclarée
|
(depuis C++17) |
Équivalence d'expressionsPlusieurs expressions e1 , e2 , ..., eN sont équivalentes en expression si toutes les conditions suivantes sont satisfaites :
e1 est équivalente en expression à e2 si et seulement si e1 et e2 sont équivalentes en expression (ce qui signifie que e2 est également équivalente en expression à e1 ). |
(depuis C++20) |
Rapports de défauts
Les rapports de défauts modifiant le comportement suivants ont été appliqués rétroactivement aux normes C++ précédemment publiées.
| DR | Appliqué à | Comportement publié | Comportement corrigé |
|---|---|---|---|
| CWG 1054 | C++98 |
l'assignation d'une valeur à une variable volatile pouvait
entraîner une lecture inutile due à la conversion lvalue-to- rvalue appliquée au résultat de l'assignation |
introduction des expressions à valeur rejetée
et exclusion de ce cas de la liste des cas nécessitant la conversion |
| CWG 1343 | C++98 |
l'ordonnancement des appels aux destructeurs dans
l'initialisation d'agrégat était sous-spécifié |
les expressions complètes dans l'initialisation d'agrégat
sont bien spécifiées |
| CWG 1383 | C++98 |
la liste des expressions où la conversion lvalue-to-rvalue
est appliquée aux expressions à valeur rejetée couvrait aussi les opérateurs surchargés |
ne couvrir que les opérateurs
avec signification native |
| CWG 1576 | C++11 |
les conversions lvalue-to-rvalue n'étaient pas appliquées
aux expressions xvalue volatile à valeur rejetée |
appliquer la conversion
dans ce cas |
| CWG 2249 | C++98 |
les identifiants à déclarer dans les déclarateurs
n'étaient pas des expressions-id |
ils le sont |
| CWG 2431 | C++11 |
les invocations des destructeurs des temporaires
liés à des références n'étaient pas des expressions complètes |
ils le sont |
Voir aussi
|
Documentation C
pour
Expressions
|