Forum: Compiler & IDEs gcc Konstante mit Komma-Operator in Ausdruck wird nicht zu letztem Ausdruck ausgewertet


von ProfessionalMagnifier (Gast)


Lesenswert?

Ich frage mich gerade, warum im folgenden Code y = 5 gesetzt wird und 
nicht = 3. Mein Compiler (GCC 4.7.2) sagt das jedenfalls und warnt auch 
nicht.

Einerseits sagt der C11-Standard und das GCC manual, dass float 
Konstanten einen Punkt als Dezimaltrennzeichen haben müssen.
OK. Dann wird das also nicht als float verstanden.

Aber dann ist es der Kommaoperator, der das Integer 3 ergibt (das dann 
in double gecasted wird).

Denn das geht doch über Assignment-Expression -> Primary-E -> Unary-E 
oder wie? Aber wäre syntaktisch hier nicht richtig.

Oder wie jetzt?
1
#include "stdio.h"
2
3
main () {
4
  double y;
5
6
  y= 5,3;
7
8
  printf("y: %.2f\n",y);
9
}

von ProfessionalMagnifier (Gast)


Lesenswert?

Umgekehrt natürlich. Unary-Expression -> Primary-Expression. Sorry.

von Peter II (Gast)


Lesenswert?

ProfessionalMagnifier schrieb:
> Ich frage mich gerade, warum im folgenden Code y = 5 gesetzt wird und
> nicht = 3. Mein Compiler (GCC 4.7.2) sagt das jedenfalls und warnt auch
> nicht.

= hat eine höhere Prio als ,
1
int x = (y= 5,3);

müsste dann aber 3 ergeben.

von ProfessionalMagnifier (Gast)


Lesenswert?

Hm. OK. Richtig. Das Ganze gibt dann zwar 3, aber zuerst mal x = 5.

Danke.

War zu K&R-Zeiten noch schöner. Da gab es eine ausdrückliche Tabelle mit 
Vorrang und Auswertungsreihenfolge und alle Syntax-Alternativen waren 
gleichberechtigt.

Naja.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

ProfessionalMagnifier schrieb:
> War zu K&R-Zeiten noch schöner.

Dürfte auch zu K&R-Zeiten dasselbe rausgekommen sein. Der Operator '=' 
hatte auch schon damals eine stärkere Bindung als ','.

Die Welt ist also hier als auch da vollkommen in Ordnung :-)

von Rolf M. (rmagnus)


Lesenswert?

ProfessionalMagnifier schrieb:
> Hm. OK. Richtig. Das Ganze gibt dann zwar 3, aber zuerst mal x = 5.

Ja. Du müßtest
1
x = (5,3);
schreiben, damit das gewünschte herauskommt. Ohne die Klammern ist es 
äquivalent zu
1
(x=5),3;

von Kaj (Gast)


Lesenswert?

Ernstgemeinte Frage: Warum sollte man so etwas tun wollen?
Wenn ich will das y den Wert 3 bekommt, dann wuerde ich einfach y = 3; 
schreiben, anstatt y = 5,3;...
Aber vielleicht denk ich mir das, in meinem jugendlichen leichtsinn, 
auch nur zu einfach. :)

von ProfessionalMagnifier (Gast)


Lesenswert?

Rolf M. schrieb:
> ProfessionalMagnifier schrieb:
>> Hm. OK. Richtig. Das Ganze gibt dann zwar 3, aber zuerst mal x = 5.
>
> Ja. Du müßtest
>
1
> x = (5,3);
2
>
> schreiben, damit das gewünschte herauskommt. Ohne die Klammern ist es
> äquivalent zu
>
1
> (x=5),3;
2
>

Das gewünschte wäre hier der Fliesskommawert 5.3 gewesen, aber dafür 
hätte da ein Punkt stehen müssen und kein Komma.

Ich habe mich nur gewundert, warum da kein Syntax-Fehler aufkommt und 
dachte ursprünglich, dass durch die erste Ziffer syntaktisch klar sein 
hätte müssen, das hier ein Literal folge (n müsse) und nur das. Und das 
wiederum, weil es sinnlos ist, an so einer Stelle den Kommaoperator zu 
verwenden, wenn die 3 dann nirgendwo zugewiesen (oder anderweitig 
verwendet) wird.
Aber die Syntax erlaubt sowas, was eigentlich entweder ausserhalb des 
ganzen Ausdrucks, wieder eine Zuweisung (oder auch einen Kontext als 
Parameter) benötigte oder nach dem Komma, damit es eine reale Wirkung 
hätte. So ist die 3 schlicht Watte; man hätte das Komma und die 3 ebenso 
weglassen können. Der Compiler macht daraus ja auch keinen Code, der 
irgendwas bewirkt.

Vielleicht sehe ich da gerade nicht alle Zusammenhänge, aber das sind so 
meine Gedanken dazu.

von (prx) A. K. (prx)


Lesenswert?

Eine Besonderheit von C gegenüber etlichen anderen Sprachen ist, dass 
Zuweisungen syntaktisch keine Statements sind, sondern Rechenausdrücke 
mit einem Ergebnis. Sie also überall stehen können, wo ein 
Rechenausdruck zulässig ist.

Das hat Folgen, manche erwünscht, manche bizarr. Die Variante hier 
gehört zu letzterer Gattung. Ist aber einfach nur ein Nebeneffekt dieser 
grundlegenden Sprachentscheidung.

Dass der Kommaoperator schwächer bindet als die Zuweisung hat einen 
simplen Grund. Weil man dadurch dies schreiben kann:
   for (i = 1, k = n; i < k; ++i, --k)
     ...

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

A. K. schrieb:
> Eine Besonderheit von C gegenüber etlichen anderen Sprachen ist, dass
> Zuweisungen syntaktisch keine Statements sind, sondern Rechenausdrücke
> mit einem Ergebnis.

Ich würd's eher so ausdrücken: Semantisch sind Zuweisungen "Expressions 
with side effekt" also Ausdrücke mit Nebeneffekt.  a = 5 ist also ein 
Ausdruck mit dem Wert 5, der als Nebeneffekt hat, a auf 5 zu setzen.

von Bernd K. (prof7bit)


Lesenswert?

ProfessionalMagnifier schrieb:
> und warnt auch
> nicht.

Er warnt doch! Schalt einfach alle Warnungen ein, so wie es sich 
gehört:

1
$ cat test.c 
2
#include "stdio.h"
3
4
int main (void) {
5
  double y;
6
  y= 5,3;
7
  printf("y: %.2f\n",y);
8
}
9
10
$ gcc test.c -Wall -Wextra
11
test.c: In function ‘main’:
12
test.c:5:7: warning: right-hand operand of comma expression has no effect [-Wunused-value]
13
   y= 5,3;
14
       ^

oder wenn Du wirklich nichts einreißen lassen willst dann gehts sogar 
noch ne ecke strenger:

1
$ gcc test.c -Wall -Wextra -Wfatal-errors -Werror
2
test.c: In function ‘main’:
3
test.c:5:7: error: right-hand operand of comma expression has no effect [-Werror=unused-value]
4
   y= 5,3;
5
       ^
6
compilation terminated due to -Wfatal-errors.
7
cc1: all warnings being treated as errors

: Bearbeitet durch User
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.