Warum zeigt dieses Programm unten keinen Fehler an?
int main (void) {
"ANGUS";
1;
3.14;
return 0;
}
Angus
Warum zeigt dieses Programm unten keinen Fehler an?
int main (void) {
"ANGUS";
1;
3.14;
return 0;
}
Lars Viklund
Jede dieser Anweisungen sind Ausdrücke, die zu einem Wert ausgewertet werden, der dann verworfen wird. Vergleichen Sie es damit, wenn Sie eine Funktion aufgerufen haben, die ein int, ein char oder ein Float zurückgegeben hat, ohne den Rückgabewert zu verwenden. Das ist auch ein Ausdruck, der zu einem Wert ausgewertet wird.
Es ist nicht ungewöhnlich, Funktionen zu haben, die Werte zurückgeben, an denen der Aufrufer interessiert sein kann oder auch nicht, wie zum Beispiel where printf("%d", 9001)
gibt die Anzahl der gedruckten Zeichen zurück. Ein Anrufer kann die zurückgegebene Nummer verwenden oder sie einfach ignorieren.
Wenn sich der Compiler beschwert, wenn Sie einen Rückgabewert ignorieren, haben Sie ein sehr lautes Build-Protokoll. Einige Compiler diagnostizieren jedoch (wenn genügend Warnflags aktiviert sind) solche sinnlosen, nebenwirkungslosen Verwendungen von Literalen und Variablen.
Füge ein Beispiel hinzu und bekomme +1 von mir … oh, egal: +1 sowieso … aber füge das Beispiel hinzu 🙂
– pmg
24. August 2011 um 9:14 Uhr
printf("Hello, world!\n");
gibt den Wert 14 zurück
– pmg
24. August 2011 um 9:16 Uhr
@pmg, mir gefällt, wie du zwei Minuten später dein eigenes Beispiel hinzugefügt hast … :p
– Johnny
30. August 2011 um 18:21 Uhr
paxdiablo
Es ist absolut gültig, dass eine Anweisung in C nur ein Wert ist, der verworfen wird. Die meisten Leute wissen nicht, dass genau das passiert, wenn sie Dinge codieren wie:
x++;
printf ("Hello, world\n");
Ersteres ist eigentlich ein Ausdruck, der zufällig den Nebeneffekt hat, die Variable zu inkrementieren, nachdem sie “zurückgegeben” wurde.
Der letztere Funktionsaufruf gibt tatsächlich einen Wert (die Anzahl der gedruckten Zeichen) zurück, der ebenfalls verworfen wird.
Von einem gewissen Standpunkt aus unterscheidet sich das nicht von den Aussagen:
42;
3 * 12;
außer der Tatsache, dass sie keine Nebenwirkungen haben, die sie nützlich machen.
Eigentlich sogar x = 1
ist ein Ausdruck, bei dem das Ergebnis verworfen wird. Das macht es aus x = y = z = 0
möglich, da dies effektiv ist:
(x = (y = (z = 1)));
All dies ist im Abschnitt C99 detailliert beschrieben 6.8.3 Expression and null statements
der auszugsweise sagt:
Der Ausdruck in einer Ausdrucksanweisung wird für seine Nebeneffekte wie Zuweisungen und Funktionsaufrufe, die Nebeneffekte haben, als ungültiger Ausdruck ausgewertet.
Es ist vollkommen gültig, dass eine Aussage nur aus einem Ausdruck besteht. In Ihren Beispielen wird damit nichts erreicht, aber es ist trotzdem vollkommen gültig.
amod
Da es in c eine gültige Anweisung ist, aber wenn Sie Java verwenden, erhalten Sie einen Kompilierzeitfehler.
Warum sollte es? Die ersten drei Zeilen in Ihrem main tun nichts und geben 0 zurück; ist ein gültiger Ausdruck.
Wenn Sie gcc zum Kompilieren des Programms verwenden, versuchen Sie, alle Warnungen zu aktivieren (mit dem Parameter -Wall). Dies würde drucken warning: statement with no effect [-Wunused-value]
Im gcc, -Wall
aktiviert nicht alle Warnungen: Es ermöglicht “Warnungen vor Konstruktionen, die einige Benutzer für fragwürdig halten” (von gcc-Dokumentation)
– pmg
24. August 2011 um 9:13 Uhr
@Mr.32 pmg hat Recht, -Wall
aktiviert nicht alle Warnungen, sondern nur “Warnungen vor Konstruktionen, die einige Benutzer für fragwürdig halten”
– Ulrich Dangel
24. August 2011 um 10:42 Uhr
return 0;
ist eine Feststellung, kein Ausdruck.
– Keith Thompson
21. September 2011 um 7:48 Uhr
Weil es gültig ist. Ein String oder eine Zahl ist ein gültiger Ausdruck und ein Ausdruck gefolgt von einem Semikolon ist eine Anweisung (auch informell als Anweisung bezeichnet).
Im gcc, -Wall
aktiviert nicht alle Warnungen: Es ermöglicht “Warnungen vor Konstruktionen, die einige Benutzer für fragwürdig halten” (von gcc-Dokumentation)
– pmg
24. August 2011 um 9:13 Uhr
@Mr.32 pmg hat Recht, -Wall
aktiviert nicht alle Warnungen, sondern nur “Warnungen vor Konstruktionen, die einige Benutzer für fragwürdig halten”
– Ulrich Dangel
24. August 2011 um 10:42 Uhr
return 0;
ist eine Feststellung, kein Ausdruck.
– Keith Thompson
21. September 2011 um 7:48 Uhr
Es ist auch in C++ gültig und hat eine hackige Verwendung in Visual Studio, wo Sie “alle Verweise finden” für eine Aufzählung möchten, Sie können die Aufzählung in einer eigenen Zeile eingeben, die mit einem Semikolon endet, und Sie können das Kontextmenü verwenden um die Referenzen zu finden.
Sie sind nur Aussagen ohne Wirkung und haben keine Regeln gebrochen.
– Stan
24. August 2011 um 9:01 Uhr
+1 für eine gut gestellte Frage.
– Flexo
♦
24. August 2011 um 9:07 Uhr
Nebenfrage: Wird der Zeichenfolge Speicher zugewiesen
"Harsha"
?– Chris Burt-Brown
24. August 2011 um 9:56 Uhr
Das habe ich mich auch schon gefragt. Da es nichts tut, ist es mit ziemlicher Sicherheit ein Tippfehler im Code, also warum beschwert sich der Compiler nicht. Eines, das ich zuvor gesehen habe, hatte die Form a;b++; wobei das mittlere Semikolon ein Punkt sein sollte. Es kam vor, dass die b-Variable sowohl unabhängig als auch als Mitglied der Struktur existierte. Kein Fehler, aber das Programm hat sich nicht wie erwartet verhalten!
– asc99c
24. August 2011 um 9:58 Uhr
@Chris: Selbst mit den grundlegendsten Optimierungsoptionen ist das Ergebnis der Kompilierung einer Quelldatei mit oder ohne die
"Harsha";
Linie ist genau die gleiche. Ohne jegliche Optimierung folgt das Konstrukt den Regeln fürstring literals
: “6.4.5/5 … Array der statischen Speicherdauer” und es werden 7 Bytes dafür zugewiesen.– pmg
24. August 2011 um 10:12 Uhr