Warum ist int x {y = 5} möglich?


10
int main() {
    int y;
    int x{ y = 5 };
    //x is 5
}

Wie ist das möglich, da y = 5 kein berechenbarer Ausdruck ist?

Warum beschwert sich der Compiler oder die IDE nicht darüber, dass main () kein int zurückgibt?


8
y = 5 ist ein Ausdruck und hat Wert 5. Warum denkst du, ist es nicht?
Nutzlos

2
Bezüglich des Fehlens returnvon mainsiehe diese Frage .
Walnuss

3
Besser noch, entfernen Sie die zweite Frage. Eine einzelne Frage pro Frage ist das bevorzugte Modell für den Stapelüberlauf.
Geschichtenerzähler - Unslander Monica

Vielleicht sollten Sie die Frage neu definieren, warum y = 5hier 5 ergibt. Die Möglichkeit von Zuweisungsoperatoren, etwas zurückzugeben, ist in der Tat eine bizarre Funktion von C / C ++.
user7860670

Antworten:


11

Ich werde von Ihrer letzten Frage ausgehen

Warum beschwert sich der Compiler oder die IDE nicht darüber, dass main () kein int zurückgibt?

Nach dem C ++ Standard (6.6.1 Hauptfunktion)

5 Eine return-Anweisung in main bewirkt, dass die main-Funktion verlassen wird (Objekte mit automatischer Speicherdauer werden zerstört) und std :: exit mit dem Rückgabewert als Argument aufgerufen wird. Wenn die Steuerung am Ende der zusammengesetzten Anweisung von main abläuft, entspricht der Effekt einer Rückgabe mit dem Operanden 0 (siehe auch 18.3).

Und relativ zu dieser Frage

Wie ist das möglich, da y = 5 kein berechenbarer Ausdruck ist?

Aus dem C ++ - Standard (8.18 Zuweisungs- und zusammengesetzte Zuweisungsoperatoren)

1 Der Zuweisungsoperator (=) und die zusammengesetzten Zuweisungsoperatoren gruppieren sich alle von rechts nach links. Alle benötigen einen modifizierbaren l-Wert als linken Operanden und geben einen l-Wert zurück, der sich auf den linken Operanden bezieht.

Sp diese Erklärung

int x{ y = 5 };

kann äquivalent in zwei Aussagen aufgeteilt werden

y = 5;
int x{ y };

Darüber hinaus können Sie in C ++ auf folgende Weise sogar auf die Variable y verweisen

int &x{ y = 5 };

Hier ist ein Demonstrationsprogramm

#include <iostream>

int main() 
{
    int y;
    int &x{ y = 5 };    

    std::cout << "y = " << y << '\n';

    x = 10;

    std::cout << "y = " << y << '\n';
}

Seine Ausgabe ist

y = 5
y = 10

Sie können diese Erklärung

int x{ y = 5 };

auch gerne umschreiben

int x = { y = 5 };

Berücksichtigen Sie jedoch, dass zwischen diesen beiden Erklärungen (ähnlich wie in den obigen Erklärungen) ein Unterschied besteht.

auto x{ y = 5 };

und

auto x = { y = 5 };

In der ersten Deklaration hat die Variable xden Typ int. In der zweiten Deklaration hat die Variable xden Typ std::initializer_list<int>.

Um den Unterschied besser sichtbar zu machen, sehen Sie, wie die Werte der Objekte ausgegeben werden.

#include <iostream>

int main() 
{
    int y;
    auto x1 { y = 5 };  

    std::cout << "x1 = " << x1 << '\n';

    auto x2 = { y = 10 };   

    std::cout << "*x2.begin()= " << *x2.begin() << '\n';

    std::cout << "y = " << y << '\n';

    return 0;
}

Die Programmausgabe ist

x1 = 5
*x2.begin()= 10
y = 10

16

Wie ist das möglich, da y = 5 kein berechenbarer Ausdruck ist?

Es handelt sich um eine Zuweisung, und Zuweisungen ergeben Werte, dh den "cv-unqualifizierten Typ des linken Operanden", siehe [expr.ass / 3] . Daraus y = 5ergibt ysich 5, was zur Initialisierung verwendet wird x.

Bezüglich Ihrer zweiten Frage siehe cppreference on main (oder [basic.start.main / 5] ):

Der Hauptteil der Hauptfunktion muss die returnAnweisung nicht enthalten : Wenn die Steuerung das Ende von main erreicht, ohne auf eine returnAnweisung zu stoßen , bewirkt dies die Ausführung return 0;.

Daher wäre ein Compiler oder eine IDE, die Sie vor einer fehlenden returnAnweisung am Ende warnt main, eindeutig falsch. Zugegeben, die Tatsache, dass Sie immer returnObjekte von Nicht- voidFunktionen ausführen sollten,main ist irgendwie ... nun, aus historischen Gründen, denke ich.


2
Ein Ausdruck kann zu einem Wert führen, aber nur eine Funktion kann returneinen. -pedantic
Useless

Ich denke das int x {y = 5}; Aussage ist nicht gültig in c
bhura

@ Bhura - die Frage ist über C ++, nicht C
StoryTeller - Unslander Monica

Vielleicht ist es erwähnenswert, dass die Rückgabe eines Wertes von main, auch wenn dies nicht erforderlich ist, normalerweise als bewährte Methode angesehen wird.
Aconcagua

4

Das operator=()Ergebnis ist ein Wert, der der Variablen zugewiesen ist. Aus diesem Grund ist es möglich, Aufgaben wie folgt zu verketten:

int x, y, z;
x = y = z = 1;

Der Zuweisungsausdruck hat einen Wert . Funktionen haben Rückgabewerte; Ausdrücke nicht.
Pete Becker

3

Wenn Sie sich die Dokumentation zu cppreference ansehen , werden Sie feststellen , dass operator=()ein Verweis auf das zugewiesene Objekt zurückgegeben wird. Daher kann eine Zuweisung als Ausdruck verwendet werden, der das zugewiesene Objekt zurückgibt.

Dann ist es nur eine normale Aufgabe mit geschweiften Klammern.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.