Strona 1 z 1
C++: wynik działania +++
: 08 mar 2011, 11:55
autor: Enkidu
Dlaczego kompilator po kodzie:
Kod: Zaznacz cały
#include <iostream>
using namespace std;
int main() {
int a = 0;
int b = 4;
int c = 9;
a = b+++c;
cout << a;
return 0;
}
wyrzuca mi sumę, czyli w tym wypadku 13? Myślałem, że inkrementacja ma większy priorytet.
Odp: C++: wynik działania +++
: 08 mar 2011, 12:11
autor: VGT
Obstawiam, ze sumowanie wykonało się w ten sposób:
Post inkrementacja odbywa się
po pobraniu wartosci b do sumowania.
Jeśli wpiszesz to tak:
Wtedy pre inkrementacja zwiększy c przed sumowaniem.
Odp: C++: wynik działania +++
: 08 mar 2011, 12:28
autor: Enkidu
Ha! ale tutaj w ogóle nie było inkremetacji, ani post ani pre, doszło do zwykłego zsumowania zmiennych.
Odp: C++: wynik działania +++
: 08 mar 2011, 12:32
autor: VGT
Enkidu pisze:Ha! ale tutaj w ogóle nie było inkremetacji[..]
A założymy się?
Kod: Zaznacz cały
#include <iostream>
using namespace std;
int main() {
int a = 0;
int b = 4;
int c = 9;
a = b+++c;
cout << a << endl << b;
return 0;
}
Skompiluj i zobacz co się stało ze zmienną b.
Chyba nie do końca rozumiesz, jak działa inkrementacja i spodziewasz się jej gdzie indziej, niż wystąpiła.
PS. Ewentualnie może wprowadzasz siebie w błąd korzystając z działania +++?
Działanie inkrementacji, to ++, który można umieścić przed lub za zmienną, czyli ++a lub a++
To co ty stworzyłeś, to połączenie inkrementacji z sumowaniem, którego nawet nigdy nie robiłem i zaskoczyło mnie, że kompilator to wykonał.
Ale skoro wykonał to właśnie nie masz kontroli, czy jest to post inkrementacja zmiennej b, czy pre inkrementacja zmiennej c.
Odp: C++: wynik działania +++
: 08 mar 2011, 15:50
autor: Enkidu
Ja z tego nie korzystam, tylko miałem na teście.
A rzeczywiście, postinkrementacja zaszła

Ale ja cały czas pytam o wynik działania - czemu najpierw sumuje a potem dopiero inkrementuje?
W tym wypadku też wyjdzie 13.
Odp: C++: wynik działania +++
: 08 mar 2011, 17:19
autor: VGT
Enkidu pisze:
W tym wypadku też wyjdzie 13.
Właśnie, że nie. Sprawdziłeś? Tutaj najpierw jest preinkrementacja, a potem sumowanie składników.
Enkidu pisze:Ale ja cały czas pytam o wynik działania - czemu najpierw sumuje a potem dopiero inkrementuje?
Bo w takiej kolejności działa postinkrementacja (w odróżnieniu od pre), a czym pisałem w pierwszym poście.
Wydaje mi się, że nie odróżniasz postinkrementacji od preinkrementacji uznając obydwie za to samo, a różnica jest zasadnicza.
Odp: C++: wynik działania +++
: 08 mar 2011, 21:08
autor: Enkidu
Uuu, racja - wyjdzie to samo. Wcześniej w pracy sprawdzałem, ale musiałem coś w kodzie namieszać.
W każdym razie zastanawiam się jak widzi to wyrażenie "a+++b" kompilator, postinkrementacje a, czy preinkrementację b? Z tego, co wyrzuca na wyjście, wynika, że widzi najpierw + przy b, a potem postinkrementację przy a.
Ale dlaczego nie widzi preinkrementacji przy b i potem sumy?
Odp: C++: wynik działania +++
: 08 mar 2011, 22:22
autor: VGT
Zapewne to kwestia podejścia kompilatora. Po prostu taka jest kolejność zapisana gdzieś w specyfikacji języka. Tak jak wcześniej pisałem, byłem zaskoczony, że coś takiego przechodzi. Dla pewności lepiej rozdzielać to spacjami. Sytuacja jest podobna, jak używanie wielu różnych operatorów bez grupowania w nawiasy. Jak wiesz, co robisz i znasz kolejność ich wykonywania, to można, ale bardzo łatwo o pomyłkę, którą potem ciężko namierzyć.
Nie zdziwiłbym się także, gdyby działanie tego "a+++b" mogło być różne w zależności od kompilatora. Na blogu Gynvael'a był ciekawy wpis o inkrementacji pokazujący, że takie sytuacje są możliwe:
http://gynvael.coldwind.pl/?id=369
PS. Ogólnie to ja nie koduję w C / C++. Mogę mieć tutaj braki w wiedzy, więc jestem nieco zawiedziony, że jako jedyny odpowiadam w tym wątku. Przydałaby się jeszcze opinia kogoś, kto jest bardziej na bieżąco
PS2. Z ciekawości przetestowałem w językach, których używam regularnie (PHP, Java) i w obydwu taki zapis jest możliwy i działa tak samo jak w C++.
Odp: C++: wynik działania +++
: 08 mar 2011, 23:25
autor: Enkidu
Myślę, że to wynika z faktu, że inkrementacja ma wyższy priorytet od znaku sumy

Ale zagadką pozostaje fakt jak w takim wypadku rozróżnia post i pre inkrementację kompilator.
Dodam, że w czystym C wynik jest ten sam.
Odp: C++: wynik działania +++
: 08 mar 2011, 23:47
autor: pax0r
C i C++ mialem juz jakis czas temu ale wydaje mi sie ze zapis a+++b to czy kompilator potraktuje to jako (a++)+b czy jako a+(++b) to jest undefined behaviour.
Odp: C++: wynik działania +++
: 09 mar 2011, 11:22
autor: Enkidu
Z tego co się orientuję undefined behaviour oznacza w praktyce jakiego kompilatora się używa

Odp: C++: wynik działania +++
: 09 mar 2011, 12:26
autor: kklimonda
Ale to chyba nie jest niezdefiniowane, w tym przypadku interpretacja jest w miare prosta.
Kompilator rozbija b+++c na zmienną b, postinkrementację, sumę, zmienną b - w kolejności, w jakiej występują w kodzie bo parser czyta kod praktycznie znak po znaku.
Kiedy już ma wszystko wczytane to najpierw wykonuje b + c, a następnie b++, znów według zasad.
Odp: C++: wynik działania +++
: 10 mar 2011, 15:40
autor: Enkidu
Tzn. że ów parser czyta znaki od lewej do prawej, ale działania wykonuje od prawej do lewej i dlatego przypisanie wygląda tak jak na przykładzie.:
a=8+c
?
Odp: C++: wynik działania +++
: 10 mar 2011, 18:25
autor: maciejewski
zgadza sie.
jest dokladnie tak jak napisales.
Odp: C++: wynik działania +++
: 12 mar 2011, 12:43
autor: Kokosek
kklimonda pisze:Ale to chyba nie jest niezdefiniowane, w tym przypadku interpretacja jest w miare prosta.
Kompilator rozbija b+++c na zmienną b, postinkrementację, sumę, zmienną b - w kolejności, w jakiej występują w kodzie bo parser czyta kod praktycznie znak po znaku.
Kiedy już ma wszystko wczytane to najpierw wykonuje b + c, a następnie b++, znów według zasad.
Dokładnie. Parser jest zachłanny (greedy), czyli dopasowuje jak największe kawałki od razu.