Namespaces
Variants

Expressions

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

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 + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b
a <=> b

a [ ... ]
* a
& a
a - > b
a. b
a - > * b
a. * b

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é
dynamic_cast convertit au sein des hiérarchies d'héritage
const_cast ajoute ou supprime les qualificateurs cv
reinterpret_cast convertit un type en un type non apparenté
C-style cast convertit un type en un autre par un mélange de static_cast , const_cast , et reinterpret_cast
new crée des objets avec une durée de stockage dynamique
delete détruit les objets précédemment créés par l'expression new et libère la zone mémoire obtenue
sizeof interroge la taille d'un type
sizeof... interroge la taille d'un pack (depuis C++11)
typeid interroge les informations de type d'un type
noexcept vérifie si une expression peut lever une exception (depuis C++11)
alignof interroge les exigences d'alignement d'un type (depuis C++11)

Conversions

Allocation de mémoire

Autre

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 :

(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.

  • char ou wchar_t
  • char16_t ou char32_t
(depuis C++11)
  • char8_t
(depuis C++20)
  • const char [ ] ou const wchar_t [ ]
  • const char16_t [ ] ou const char32_t [ ]
(depuis C++11)
  • const char8_t [ ]
(depuis C++20)
(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)
  • si E est une expression lambda , l'initialisation des entités capturées par copie et les expressions constitutives de l'initialiseur des captures,
(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)
(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

  • elle est l'opérande de l'opérateur sizeof , ou
  • elle est l'opérande de l'opérateur typeid et ne désigne pas une lvalue de type classe polymorphe .
(jusqu'en C++11)

Les opérandes suivants sont des opérandes non évalués , ils ne sont pas évalués :

  • les expressions auxquelles s'applique l'opérateur typeid , sauf les glvalues de types classes polymorphes
  • les expressions qui sont des opérandes de l'opérateur sizeof
  • les opérandes de l'opérateur noexcept
  • les opérandes du spécificateur decltype
(depuis C++20)

Une expression est potentiellement évaluée sauf si

  • elle est un opérande non évalué, ou
  • elle est une sous-expression d'un opérande non évalué.
(depuis C++11)

Les expressions potentiellement évaluées sont ODR-use .

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 [[ nodiscard ]] .

(depuis C++17)

Équivalence d'expressions

Plusieurs expressions e1 , e2 , ..., eN sont équivalentes en expression si toutes les conditions suivantes sont satisfaites :

  1. Elles ont les mêmes effets.
  2. Soit elles sont toutes des sous-expressions constantes , soit aucune ne l'est.
  3. Soit elles sont toutes noexcept , soit aucune ne l'est.

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