Warum sollte man keine versteckten Anweisungen in logischen Ausdrücken ausführen lassen?
-
Was damals der Grund war es ursprünglich so zu machen ist die eine Frage.
Was der Grund war weswegen es mit C++11 bzw. C++14 nicht geändert wurde ist eine andere Frage.
Kann der selbe Grund sein, muss aber nicht.
-
NineT4 schrieb:
Sorry Es sollte so aussehen:
ich habe "n" an Stelle von "m" geschriebenif (n > 100 && m++ > 100){ //tue etwas }
if(n > 100 && m+1 > 100){ m++; //tue etwas }
Das ist nicht das gleiche.
if (n > 100 ) m++ if ( m > 100) { //tue etwas } }
Das ist wie das erste Beispiel, aber ganz einfach lesbar.
-
- signed overflow war schon immer UB (im Gegensatz zur signed (integralen) promotion, die schon immer IB war)
- unsigned overflow war schon immer defined (wrap around), was ich persönlich für den praktischen Gebrauch für Unsinn halte, da hier Überläufe (stillschweigend und standardkonform!) verschleiert werden; ich möchte nicht wissen, wieviele Software in kritischen Bereichen im Umlauf ist, die dieses "Stillschweigen" aus Sorg- oder/und Ahnungslosigkeit "verwenden"
- der Standard macht (naturgemäß) keine Vorgaben für Implementierungsvarianten geschweige denn Optimierungen
- der Standard sieht aber sehr wohl prinzipielle Möglichkeiten vor, um solche fragilen Konstrukte sichtbar zu machen, er spricht z.B. von "the result is implementation-defined or an implementation-defined signal is raised" und bei UB spricht er sogar explizit davon, dass eine Implementierung (also ein Compiler) eine UB in eine constraint-violation umwandeln darf, die dann wiederum standardgemäß auch ein "signal" in irgendeiner Form von sich geben muss
-
lesenkönnen schrieb:
if (n > 100 ) m++ if ( m > 100) { //tue etwas } }
Das ist wie das erste Beispiel, aber ganz einfach lesbar.
Mal abgesehen davon dass ein ";" fehlt...
Nein, ist nicht "wie das erste Beispiel".
Das Thema war aber eigentlich schon durch.
-
hustbaer schrieb:
lesenkönnen schrieb:
if (n > 100 ) m++ if ( m > 100) { //tue etwas } }
Das ist wie das erste Beispiel, aber ganz einfach lesbar.
Mal abgesehen davon dass ein ";" fehlt...
Nein, ist nicht "wie das erste Beispiel".
Das Thema war aber eigentlich schon durch.Und eine { fehlt auch.
Aber#include <iostream> using namespace std; int main() { int n = 180; int m = 80; if (n > 100 && m++ > 100){ //tue etwas } std::cout << "n: " << n << " m: " << m; // your code goes here return 0; }
n: 180 m: 81
#include <iostream> using namespace std; int main() { int n = 180; int m = 80; if(n > 100 && m+1 > 100){ m++; //tue etwas } std::cout << "n: " << n << " m: " << m; // your code goes here return 0; }
n: 180 m: 80
#include <iostream> using namespace std; int main() { int n = 180; int m = 80; if (n > 100 ) { m++; if ( m > 100) { //tue etwas } } std::cout << "n: " << n << " m: " << m; // your code goes here return 0; }
n: 180 m: 81
Der Compiler macht doch aus jedem && wieder ein geschachteltes if.
Zeigt ein Beispiel wo bei 1 und 3 nicht das gleiche raus kommt.
-
n = 101
m = 100
Wird "tue etwas" ausgeführt oder nicht?
Im Original nicht.
In deiner Variante schon.Hatten wir aber wie gesagt alles schon durch.
https://www.c-plusplus.net/forum/p2478891#2478891
-
Igitt, wer hat denn so einen Bug in die Sprache eingebaut? Irgendwas links und rechts vom Vergleichsoperator nach dem Vergleich auszuführen ist doch total kontraintuitiv.
-
Das hat doch mit dem Vergleich nix zu tun.
Ist halt die Semantik von
n++
. Post increment halt.
Auch ganz ohne if:int x = 100; printf("%d\n", x++); // Schreibt 100 raus printf("%d\n", x); // Schreibt 101 raus
-
Gibt es ein Beispiel wo man Post increment sinnvoll braucht?
-
Brauchen ist relativ.
Unbedingt brauchen tut man grundsätzlich nie mehr als was eben nötig ist um eine Sprache Turing-complete zu machen. (Manchmal sogar weniger, aber eben nie mehr.)Viele Dinge die darüber hinausgehen sind aber praktisch.
Verwendet wird post-increment oft in Schleifen für Zeiger, Iteratoren oder Indizes.
Ich persönlich verwende post-increment sehr sparsam. Bzw. meist nur mit eingebauten Typen (
int
, ...) und wenn ich den Wert des post-increment Ausdrucks gar nicht verwende.
Wie halt in der "klassischen for Schleife"for (int i = 0; i < something; i++)
Beispiel das ohne post-increment wirklich deutlich hässlicher wäre fällt mir jetzt auf die Schnelle keines ein.
-
hustbaer schrieb:
Beispiel das ohne post-increment wirklich deutlich hässlicher wäre fällt mir jetzt auf die Schnelle keines ein.
Wenn man kurzen Code schön findet, dann sind die Stringverarbeitungsfunktionen aus der C-Standardbibliothek gute Anwendungsgebiete für Postinkrement. Da kann man ein paar schicke Ein- und Zweizeiler schreiben, wo man sonst ein bisschen mehr Code bräuchte. Beispielsweise ist ein (naives) strcpy schreibbar als
while(*dest++ = *src++);
Das fällt alles in die Kategorie "Schleifen für Zeiger, Iteratoren oder Indizes".
-
Genau.
Muss man aber nicht schön finden.
Und "sinvoll brauchen" ist halt eben ne sehr subjektive Sache.EDIT: Wobei...
Wenn man das Beispiel (abgesehen von der Schleife) etwas "umschreibt" zu...dest.WriteAndMoveToNext(src.ReadAndMoveToNext());
...sieht man dass die darin verwendeten Konstrukte - "WriteAndMoveToNext" und "ReadAndMoveToNext" - gar nicht so komisch sind.
Im Gegenteil, sie sind sogar so "üblich", dass das "AndMoveToNext" im Namen oft weggelassen wird. z.B. bei typsichen File-IO Klassen.