C++ andere Bedeutung der Mehrfachzuweisung

OP #5911475
Lesenswert?

In C++ sieht man ja oft solche Mehrfachzuweisungen:
1
counter = flankenerkennung = entprellen = taster;
Unter C ist die Bedeutung eindeutig, alle Variablen werden auf den 
gleichen Wert gesetzt.
Unter C++ ist die Bedeutung aber eine völlig andere. Wo kann man 
nachlesen, was das bedeutet?
Gast #5911479
Lesenswert?

Peter D. schrieb:
> In C++ sieht man ja oft solche Mehrfachzuweisungen:counter =
> flankenerkennung = entprellen = taster;
> Unter C ist die Bedeutung eindeutig, alle Variablen werden auf den
> gleichen Wert gesetzt.

Nein, dass ist nicht der fall.
1
flankenerkennung = entprellen = taster;
entspricht:
1
entprellen = taster;
2
flankenerkennung = entprellen;

Insbesondere wenn entprellen volatile ist kann sich das zwischendurch 
durchaus ändern.
#5911566
Lesenswert?

Und all das bräuchte nicht weiter diskutiert werden, wenn man solche 
Konstrukte einfach nicht nutzt.

Oliver
P.S:
Häufig sieht man das auch in C++ eigentlich überhaupt nicht. Da gibt es 
eigentlich hier nur den einen, der das Beispiel von oben auch verbrochen 
hat.

Das Beispiel zeigt genau den Grund, warum man das nicht machen soll. Das 
sieht der Verursacher zwar anders (der findet seine Idee toll), aber 
egal. Murks bleibt Murks.
#5911850
Lesenswert?

Peter D. schrieb:
> In C++ sieht man ja oft solche Mehrfachzuweisungen:
>
1
> counter = flankenerkennung = entprellen = taster;
2
>
> Unter C ist die Bedeutung eindeutig, alle Variablen werden auf den
> gleichen Wert gesetzt.
> Unter C++ ist die Bedeutung aber eine völlig andere. Wo kann man
> nachlesen, was das bedeutet?

Der Kopierzuweisungsoperator ist ein C++ ein Operator, den man selbst 
definieren und überladen kann. Was der Operator dann tut, ist der 
Sprache egal. Allerdings (wie oben schon geschrieben), sollte man dabei 
die übliche Erwartungshaltung erfüllen, und zwar der Operator (etwa bei: 
lhs = rhs) hat als Resultat das lhs-Objekt und übt einen bestimmten 
Seiteneffekt auf lhs aus, nämlich kopiert die non-const Attribute.
Moderator #5911873
Lesenswert?

DPA schrieb:
> Peter D. schrieb:
>> In C++ sieht man ja oft solche Mehrfachzuweisungen:counter =
>> flankenerkennung = entprellen = taster;
>> Unter C ist die Bedeutung eindeutig, alle Variablen werden auf den
>> gleichen Wert gesetzt.
>
> Nein, dass ist nicht der fall.
>
>  flankenerkennung = entprellen = taster;
>
> entspricht:
>
>  entprellen = taster;
>  flankenerkennung = entprellen;
>
> Insbesondere wenn entprellen volatile ist kann sich das zwischendurch
> durchaus ändern.

Auch implizite Typkonvertierungen können zu Unterschieden führen:

1
#include <stdio.h>
2
#include <stdint.h>
3

4
int main(void) {
5
  double d;
6
  int16_t i16;
7
  uint8_t ui8;
8

9
  ui8 = i16 = d = -1234.5;
10

11
  printf("d=%f, i16=%d, u8=%u\n", d, i16, ui8);
12
}

ergibt

1
d=-1234.500000, i16=-1234, u8=46


Olaf B. schrieb:
> wird bei Ruby öfters verwandt. In C++ nicht.

In Ruby und Python ist die Zuweisung an gewöhnliche Variablen (also
keine Membervariablen) nicht überladbar, und es gibt keine impliziten
Typkonvertierungen, weswegen es dort diesbezüglich keine Überraschungen
gibt.

Ich verwende die Mehrfachzuweisung auch in C und C++, aber nur für
primitive Datentypen (int, double usw.) und nur für Variablen gleichen
Typs. Damit sind Überraschungen ebenfalls ausgeschlossen.


Oliver S. schrieb:
> Das o.a. Beispiel stammt von hier:
>
> Beitrag "Re: C/C++ Objektmethoden"

Das ist wirklich gruselig, noch gruseliger als die Vergewaltigung der
Bitshift- als I/O-Operatoren in iostream. Hätte der Fanboy statt des =
wenigstens das ohnehin schon versaute << genommen, wäre die Überraschung
nicht ganz so heftig.
Moderator #5911923
Lesenswert?

Heiko L. schrieb:
> Nur, dass << von links nach rechts ausgewertet wird.

Stimmt. Dann also andersherum:

1
  taster >> entprellen >> flankenerkennung >> counter;

Das passt ohnehin besser zu der hierzulande üblichen Leserichtung.

Oder auch

1
  taster | entprellen | flankenerkennung | counter;

Das erinnert an eine Shell-Pipline, die eine ähnliche Funktion hat.

Ein Rest des bösen Überraschungseffekts bleibt aber dennoch.

Warum müssen dafür unbedingt die Operatoren missbraucht werden, wenn es
auch mit benamsten Memberfunktionen geht?

Also so:

1
taster.pipe(entprellen).pipe(flankenerkennung).pipe(counter);

Oder, wenn die Memberfunktionsnamen eher wie Infixoperatoren aussehen
sollen, so:

1
taster .pipe (entprellen) .pipe (flankenerkennung) .pipe (counter);
#5912660
Lesenswert?

Ja, richtig. Bei dem Beispiel mit den Zuweisungen würde ich davon 
ausgehen, dass das Objekt ganz Rechts, also "taster", const sein könnte. 
Beim >> würde ich darauf nicht wetten.
Insgesamt wäre ich bei Operatoren vorsichtig, ihnen eine Bedeutung zu 
geben, die nicht "vom Standard diktiert" wurde. Wenn die Bedeutung kein 
common-sense ist, führt der Verzicht auf die Benamung schlicht dazu, 
dass man nur noch mit irgendeinem wildcard-symbol konfrontiert ist. 
Schlimmer noch, als das bei benannten Funktionen z.T. schon der Fall 
ist.
Die >>-Kette gibt z.B. klassischer Weise das Objekt links zurück, nicht 
das rechte.
#5913029
Lesenswert?

Heiko L. schrieb:
> Insgesamt wäre ich bei Operatoren vorsichtig, ihnen eine Bedeutung zu
> geben, die nicht "vom Standard diktiert" wurde. Wenn die Bedeutung kein
> common-sense ist, führt der Verzicht auf die Benamung schlicht dazu,
> dass man nur noch mit irgendeinem wildcard-symbol konfrontiert ist.

Dann schau dir mal boost.spirit an. Da treiben sie die Operator Abuse 
auf die Spitze. Siehe https://de.wikipedia.org/wiki/Spirit_(Parser)
#5913062
Lesenswert?

Rolf M. schrieb:
> Heiko L. schrieb:
>> Insgesamt wäre ich bei Operatoren vorsichtig, ihnen eine Bedeutung zu
>> geben, die nicht "vom Standard diktiert" wurde. Wenn die Bedeutung kein
>> common-sense ist, führt der Verzicht auf die Benamung schlicht dazu,
>> dass man nur noch mit irgendeinem wildcard-symbol konfrontiert ist.
>
> Dann schau dir mal boost.spirit an. Da treiben sie die Operator Abuse
> auf die Spitze. Siehe https://de.wikipedia.org/wiki/Spirit_(Parser)

Wobei das ein in sich abgeschlossenes Modul ist und die Operatoren 
keinerlei Verwendung außerhalb der Definition der Grammatik anstreben.
#5913204
Lesenswert?

Heiko L. schrieb:
> Rolf M. schrieb:
>> Heiko L. schrieb:
>>> Insgesamt wäre ich bei Operatoren vorsichtig, ihnen eine Bedeutung zu
>>> geben, die nicht "vom Standard diktiert" wurde. Wenn die Bedeutung kein
>>> common-sense ist, führt der Verzicht auf die Benamung schlicht dazu,
>>> dass man nur noch mit irgendeinem wildcard-symbol konfrontiert ist.
>>
>> Dann schau dir mal boost.spirit an. Da treiben sie die Operator Abuse
>> auf die Spitze. Siehe https://de.wikipedia.org/wiki/Spirit_(Parser)
>
> Wobei das ein in sich abgeschlossenes Modul ist und die Operatoren
> keinerlei Verwendung außerhalb der Definition der Grammatik anstreben.

Die Grammatik hat aber nichts mit der Semantik zu tun!
Da verwechselt Du was. Es gibt nichts außerhalb der Grammatik bei einer 
formalen Sprache.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren