Postinkrementoperator bei If-Anweisung


  • Mod

    seldon schrieb:

    Nicht definiert ist der Wert von s.b und s.c bei

    int a = 0;
    struct { int b, c; } s = { a++, a++ };
    

    Das sollte eigentlich definiert sein. Jedenfalls sehe ich keinen signifikanten Unterschied zu

    int a = 0;
    int b = a++, c = a++;
    


  • seldon schrieb:

    Sequenzpunkte sind: [...]

    Schön, mal einen ausführlichen Überblick zu haben. Punkt 6-7 kannte ich nicht, wie ist Punkt 5 zu verstehen? Der Aufrufer der Standardbibliotheksfunktion kann sich ja teilweise nicht auf die Aufrufreihenfolge verlassen, was bringt also ein Sequenzpunkt im aufrufenden Ausdruck?

    __-- schrieb:

    diese sequenzpunkte liegen imho in c/c++ an der falschen stelle und führen zu total unerwarteten ergebnissen.

    Wenn dein Beitrag nicht als Getrolle aufgefasst werden soll, musst du schon etwas konkreter werden. Was findest du denn "total unerwartet"?



  • Nexus schrieb:

    __-- schrieb:

    diese sequenzpunkte liegen imho in c/c++ an der falschen stelle und führen zu total unerwarteten ergebnissen.

    Wenn dein Beitrag nicht als Getrolle aufgefasst werden soll, musst du schon etwas konkreter werden. Was findest du denn "total unerwartet"?

    Dieser __-- ist nur ein ungebildeter C-Troll. Einfach ignorieren.



  • Also wenn ich mir diese Liste hier ansehe, dann ist die Reihenfolge und somit die Nebeneffekte sehr Wohl definiert. Oder meinst du etwas anderes?

    http://www.highscore.de/cpp/einfuehrung/operatoren.html#präzedenztabelle



  • int a = 0; 
    int b = 0;
    if(a++ || b--) 
       b = a;
    
    std::cout << a << "\n";
    std::cout << b << "\n";
    
    if(a++ && b--)
       b = 15;
    
    std::cout << a << "\n";
    std::cout << b << "\n";
    

    Ist das Ergebnis definiert oder undefiniert?
    Ich bekomme: 1, -1, 2, 15



  • int a = 0;
    int b = 0;
    if(a++ || b--)		// a == 0 || b == 0; a++, b--
       b = a;		// wird ignoriert, da false or false == false
    
    std::cout << a << "\n";	//	a == 1
    std::cout << b << "\n";	//	b == -1
    
    if(a++ && b--)		// a == 1 && b == -1; a++, b--
       b = 15;		// da true && true == true
    
    std::cout << a << "\n";	//	a == 2
    std::cout << b << "\n"	//	b == 15
    

    Und damit definiert. Wobei der Code auch noch gut zu lesen ist.


  • Mod

    Nick Unbekannt schrieb:

    Und damit definiert. Wobei der Code auch noch gut zu lesen ist.

    edit: Siehe unten. Es ist nicht deswegen definiert. Auch bei undefiniertem Verhalten bekommt man irgendein Ergebnis. Aber es kann von Compiler zu Compiler unterschiedlich sein.

    Ein Beispiel dafür wäre

    void foo(int a, int b)
    {
     cout<<a<<b;
    }
    
    //...
    
    int i=1;
    foo(i++,i++);
    

    12 oder 21?

    Das Ergebnis des Beispiels von WirklichSchlechterCode ist aber soweit ich das sehe vollständig definiert, da || und && als Sequenzpunkte fungieren und zudem die Reihenfolge der Auswertung (bzw. Nichtauswertung) bei diesen Operatoren genau festgelegt ist.

    edit: @Nick Unbekannt: Im zweiten Lesen merke ich, ich habe dich missverstanden. Du meintest das gleiche wie ich, warum der Code definiertes Verhalten zeigt. Vergiss daher meine Eingangsbemerkung.



  • Nick Unbekannt schrieb:

    Also wenn ich mir diese Liste hier ansehe, dann ist die Reihenfolge und somit die Nebeneffekte sehr Wohl definiert. Oder meinst du etwas anderes?

    http://www.highscore.de/cpp/einfuehrung/operatoren.html#präzedenztabelle

    Andere Baustelle, die Vorrangregeln sagen nichts über die Abarbeitungsreihenfolge aus.



  • SeppJ schrieb:

    12 oder 21?

    Sollte auch definiert sein.
    http://en.wikipedia.org/wiki/X86_calling_conventions



  • Nick Unbekannt schrieb:

    Sollte auch definiert sein.
    http://en.wikipedia.org/wiki/X86_calling_conventions

    Das hat damit nichts zu tun (davon abgesehen, dass auch unterschiedliche Calling-Conventions verwendet werden können). Es ist implementation-defined, in welcher Reihenfolge die Inkrementierungen abgearbeitet werden.

    Deshalb gibt es auch auf der Seite von boost::shared_ptr einen Hinweis unter "Best Practices" im Bezug auf temporäre shared_ptr -Objekte als Funktionsargumente.



  • Vielen vielen herzlichen Dank für all die guten Beiträge! 👍
    Vorallem der von seldon war klasse!!!


Anmelden zum Antworten