Namensräume
Varianten
Aktionen

Ausdrücke

Von cppreference.com
< cpp‎ | Sprache
 
 
C++ Sprache
Allgemeine Themen
Kontrollfluss
Bedingte Ausführungsaussagen
if
Iterationsanweisungen (Schleifen)
for
Bereichs-for (C++11)
Sprunganweisungen
Funktionen
Funktionsdeklaration
Lambda-Funktionsausdruck
inline-Spezifizierer
Dynamische Ausnahmespezifikationen (bis C++17*)
noexcept-Spezifizierer (C++11)
Ausnahmen
Namensräume
Typen
Spezifizierer
const/volatile
decltype (C++11)
auto (C++11)
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Speicherdauer-Spezifizierer
Initialisierung
Ausdrücke
Alternative Darstellungen
Literale
Boolesch - Ganzzahl - Gleitkommazahl
Zeichen - String - nullptr (C++11)
Benutzerdefinierte (C++11)
Dienstprogramme
Attribute (C++11)
Typen
typedef-Deklaration
Typalias-Deklaration (C++11)
Umwandlungen
Speicherzuweisung
Klassen
Klassenspezifische Funktionseigenschaften
explicit (C++11)
static

Spezielle Member-Funktionen
Templates
Sonstiges
 
 

Ein Ausdruck ist eine Sequenz von Operatoren und ihren Operanden, die eine Berechnung spezifiziert.

Die Auswertung eines Ausdrucks kann ein Ergebnis liefern (z. B. liefert die Auswertung von 2 + 2 das Ergebnis 4) und Nebenwirkungen hervorrufen (z. B. druckt die Auswertung von std::printf("%d", 4) das Zeichen '4' auf der Standardausgabe).

Jeder C++-Ausdruck wird durch zwei unabhängige Eigenschaften charakterisiert: einen Typ und eine Wertkategorie.

Inhalt

[bearbeiten] Allgemein

  • Wertkategorien (lvalue, rvalue, glvalue, prvalue, xvalue(seit C++11)) klassifizieren Ausdrücke nach ihren Werten
  • Auswertungsreihenfolge von Argumenten und Teilausdrücken spezifiziert die Reihenfolge, in der Zwischenergebnisse erzielt werden

[bearbeiten] Operatoren

Häufige Operatoren
Zuweisung Inkrement
Dekrement
Arithmetik Logisch Vergleich Member
Zugriff
Sonstiges

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

Funktionsaufruf

a(...)
Komma

a, b
Ternär

a ? b : c
Spezielle Operatoren

static_cast konvertiert einen Typ in einen anderen verwandten Typ
dynamic_cast konvertiert innerhalb von Vererbungshierarchien
const_cast fügt cv-Qualifizierer hinzu oder entfernt sie
reinterpret_cast konvertiert einen Typ in einen nicht verwandten Typ
C-Stil Cast konvertiert einen Typ in einen anderen durch eine Mischung aus static_cast, const_cast und reinterpret_cast
new erstellt Objekte mit dynamischer Speicherverwaltung
delete zerstört zuvor mit new-Ausdruck erstellte Objekte und gibt den zugewiesenen Speicherbereich frei
sizeof fragt die Größe eines Typs ab
sizeof... fragt die Größe eines packs ab (seit C++11)
typeid fragt die Typinformationen eines Typs ab
noexcept prüft, ob ein Ausdruck eine Ausnahme auslösen kann (seit C++11)
alignof fragt die Ausrichtungsvoraussetzungen eines Typs ab (seit C++11)

[bearbeiten] Konvertierungen

[bearbeiten] Speicherzuweisung

[bearbeiten] Sonstiges

[bearbeiten] Primärausdrücke

Die Operanden eines jeden Operators können andere Ausdrücke oder Primärausdrücke sein (z. B. in 1 + 2 * 3 sind die Operanden von operator+ der Teilausdruck 2 * 3 und der Primärausdruck 1).

Primärausdrücke sind einer der folgenden

(seit C++26)
(seit C++11)
(seit C++17)
(seit C++20)

Jeder Ausdruck in Klammern wird ebenfalls als Primärausdruck klassifiziert: Dies garantiert, dass die Klammern eine höhere Priorität als jeder Operator haben. Klammern erhalten Wert, Typ und Wertkategorie.

[bearbeiten] Literale

Literale sind die Token eines C++-Programms, die Konstanten Werte darstellen, die im Quellcode eingebettet sind.

  • char oder wchar_t
  • char16_t oder char32_t
(seit C++11)
  • char8_t
(seit C++20)
  • const char[] oder const wchar_t[]
  • const char16_t[] oder const char32_t[]
(seit C++11)
  • const char8_t[]
(seit C++20)
(seit C++11)

[bearbeiten] Vollständige Ausdrücke

Ein konstituierender Ausdruck wird wie folgt definiert

  • Der konstituierende Ausdruck eines Ausdrucks ist dieser Ausdruck.
  • Die konstituierenden Ausdrücke einer in geschweifte Klammern eingeschlossenen Initialisierungsliste oder einer (möglicherweise geklammerten) Auswahlliste sind die konstituierenden Ausdrücke der Elemente der jeweiligen Liste.
  • Die konstituierenden Ausdrücke eines Initialisierers, der mit = beginnt, sind die konstituierenden Ausdrücke der Initializer-Klausel.
int num1 = 0;
num1 += 1; // Case 1: the constituent expression of “num += 1” is “num += 1”
 
int arr2[2] = {2, 22} // Case 2: the constituent expressions
                      //         of “{2, 22}” are “2” and “22”
                      // Case 3: the constituent expressions of “= {2, 22}”
                      //         are the constituent expressions of “{2, 22}”
                      //         (i.e. also “2” and “22”)

Die unmittelbaren Teilausdrücke eines Ausdrucks E sind

  • die konstituierenden Ausdrücke von Es Operanden,
(seit C++14)
  • wenn E ein Lambda-Ausdruck ist, die Initialisierung der per Kopie erfassten Entitäten und die konstituierenden Ausdrücke des Initialisierers der Erfassungen,
(seit C++11)
  • jeder Funktionsaufruf, den E implizit aufruft, oder
  • wenn E ein Funktionsaufruf ist oder implizit eine Funktion aufruft, die konstituierenden Ausdrücke jedes Standardarguments, das im Aufruf verwendet wird.

Ein Teilausdruck eines Ausdrucks E ist ein unmittelbarer Teilausdruck von E oder ein Teilausdruck eines unmittelbaren Teilausdrucks von E. Beachten Sie, dass Ausdrücke, die im „Funktionskörper“ von Lambda-Ausdrücken vorkommen, keine Teilausdrücke des Lambda-Ausdrucks sind.(seit C++11)

Die folgenden Ausdrücke sind vollständige Ausdrücke 

(seit C++20)
(seit C++26)
  • Ausdrücke, die kein Teilausdruck eines anderen Ausdrucks sind und die nicht anderweitig Teil eines vollständigen Ausdrucks sind

Wenn eine Sprachkonstruktion definiert ist, einen impliziten Funktionsaufruf zu erzeugen, wird die Verwendung der Sprachkonstruktion für die Zwecke dieser Definition als Ausdruck betrachtet. Konvertierungen, die auf das Ergebnis eines Ausdrucks angewendet werden, um die Anforderungen der Sprachkonstruktion zu erfüllen, in der der Ausdruck vorkommt, gelten ebenfalls als Teil des vollständigen Ausdrucks.

Bei einem Initialisierer gilt die Durchführung der Initialisierung der Entität (einschließlich der Auswertung von Standard-Member-Initialisierern eines Aggregats)(seit C++14) ebenfalls als Teil des vollständigen Ausdrucks.

[bearbeiten] Potenziell ausgewertete Ausdrücke

Ein Ausdruck ist potenziell ausgewertet, es sei denn

  • er ist der Operand des sizeof-Operators, oder
  • er ist der Operand des typeid-Operators und bezeichnet kein lvalue eines polymorphen Klassentyps.
(bis C++11)

Die folgenden Operanden sind nicht ausgewertete Operanden, sie werden nicht ausgewertet

  • Ausdrücke, auf die der typeid-Operator angewendet wird, außer glvalues von polymorphen Klassentypen
  • Ausdrücke, die Operanden des sizeof-Operators sind
  • Operanden des noexcept-Operators
  • Operanden des decltype-Spezifizierers
(seit C++20)

Ein Ausdruck ist potenziell ausgewertet, es sei denn

  • er ist ein nicht ausgewerteter Operand, oder
  • er ist ein Teilausdruck eines nicht ausgewerteten Operanden.
(seit C++11)

Potenziell ausgewertete Ausdrücke sind ODR-use.

[bearbeiten] Ausdrücke mit verworfenem Wert

Ein Ausdruck mit verworfenem Wert ist ein Ausdruck, der nur wegen seiner Nebenwirkungen verwendet wird. Der aus einem solchen Ausdruck berechnete Wert wird verworfen. Solche Ausdrücke umfassen den vollständigen Ausdruck jedes Ausdrucks-Statements, den linken Operanden des eingebauten Komma-Operators oder den Operanden eines Cast-Ausdrucks, der zu void castet.

Array-zu-Zeiger- und Funktions-zu-Zeiger-Konvertierungen werden niemals auf den von einem Ausdruck mit verworfenem Wert berechneten Wert angewendet. Die lvalue-zu-rvalue-Konvertierung wird genau dann angewendet, wenn der Ausdruck ein volatile-qualifizierter glvalue ist und eine der folgenden Formen hat (eingebaute Bedeutung erforderlich, möglicherweise geklammert)

  • id-expression,
  • Array-Subskript-Ausdruck,
  • Klassen-Member-Zugriffs-Ausdruck,
  • Indirektion,
  • Zeiger-auf-Member-Operation,
  • bedingter Ausdruck, bei dem sowohl der zweite als auch der dritte Operand einer dieser Ausdrücke sind,
  • Komma-Ausdruck, bei dem der rechte Operand einer dieser Ausdrücke ist.

Zusätzlich ist, wenn das lvalue von einem volatile-qualifizierten Klassentyp ist, ein volatile-Kopierkonstruktor erforderlich, um das resultierende rvalue-Temporär-Objekt zu initialisieren.

Wenn der Ausdruck ein nicht-void prvalue ist (nach allen möglicherweise stattgefundenen lvalue-zu-rvalue-Konvertierungen), erfolgt eine temporäre Materialisierung.

Compiler können Warnungen ausgeben, wenn ein Ausdruck (außer Cast zu void) einen als [[nodiscard]] deklarierten Wert verwirft.

(seit C++17)

Ausdrucks-Äquivalenz

Eine Anzahl von Ausdrücken e1, e2, ..., eN sind ausdrucks-äquivalent, wenn alle folgenden Bedingungen erfüllt sind

  1. Sie haben die gleichen Effekte.
  2. Entweder sind sie alle konstante Teilausdrücke oder keiner ist es.
  3. Entweder sind sie alle noexcept oder keiner ist es.

e1 ist ausdrucks-äquivalent zu e2, wenn und nur wenn e1 und e2 ausdrucks-äquivalent sind (was bedeutet, dass e2 auch ausdrucks-äquivalent zu e1 ist).

(seit C++20)

[bearbeiten] Defect Reports

Die folgenden Verhaltensändernden Fehlerberichte wurden rückwirkend auf zuvor veröffentlichte C++-Standards angewendet.

DR angewendet auf Verhalten wie veröffentlicht Korrigiertes Verhalten
CWG 1054 C++98 Zuweisung eines Wertes an eine volatile Variable kann
zu einer unnötigen Lesung führen aufgrund der lvalue-zu-
rvalue-Konvertierung, die auf das Zuweisungsergebnis angewendet wird
Ausdrücke mit verworfenem Wert einführen
und diesen Fall aus der Liste ausschließen
der Fälle, die die Konvertierung erfordern
CWG 1343 C++98 Die Sequenzierung von Destruktoraufrufen in
der Aggregat-Initialisierung war nicht ausreichend spezifiziert
Vollständige Ausdrücke in der Aggregat-Initialisierung
sind gut spezifiziert
CWG 1383 C++98 Die Liste der Ausdrücke, bei denen die lvalue-zu-rvalue-
Konvertierung auf Ausdrücke mit verworfenem Wert angewendet wird
deckte auch überladene Operatoren ab
nur Operatoren abdecken
mit eingebauter Bedeutung
CWG 1576 C++11 lvalue-zu-rvalue-Konvertierungen wurden nicht angewendet
auf volatile xvalue-Ausdrücke mit verworfenem Wert
die Konvertierung anwenden
in diesem Fall
CWG 2249 C++98 Bezeichner, die in Deklaratoren deklariert werden sollen
waren keine id-expressions
sie sind
CWG 2431 C++11 die Aufrufe der Destruktoren von Temporär-Objekten, die
an Referenzen gebunden sind, waren keine vollständigen Ausdrücke
sie sind

[bearbeiten] Siehe auch

C-Dokumentation für Ausdrücke