• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Klasowo - obiektowe machlojki

VPS Starter Arubacloud
0 głosów
250 wizyt
pytanie zadane 23 kwietnia 2017 w C i C++ przez rattle Użytkownik (510 p.)
edycja 23 kwietnia 2017 przez rattle

 

#include <iostream>
using namespace std;
class A {
public:
    A()
    {
        cout<<"konstruktor\n";
        a=0;
    }
    int a;
    int b(void);
};
int A::b(void) { return ++a; };
int main(void) {

    A a;
    cout << "w: " << a.a << "\n";
    cout << a.b() << " " << a.a << "\n"; 
    cout << a.a << "\n"; 
    return 0;
}


 

Dlaczego a.a mimo, że zostało zinkrementowane w metodzie b() to wypisuje się jako 0 ?

Gdy w nastepnej linijce wypisałem to znowu to już widnieje jako 1. O co chodzi?

Wygląda, że

cout<<funkcja()<<zmienna<<endl;

to nie to samo co

cout<<funkcja();

cout<<zmienna<<endl; 

Ale czemu?

2 odpowiedzi

+3 głosów
odpowiedź 23 kwietnia 2017 przez mokrowski Mędrzec (156,260 p.)
wybrane 24 kwietnia 2017 przez rattle
 
Najlepsza

Jest to związane z tzw. punktem sekwencyjnym. https://en.wikipedia.org/wiki/Sequence_point

Standard języka C i C++ definiują że twórcy kompilatora na danej platformie sami ustalają kolejność wykonywania działań operacji tak aby było one wydajne na danej platformie i danym kompilatorze. Pobieranie i zmiana danych w obrębie 1 punktu sekwencyjnego kończy się niezdefiniowanym zachowaniem.

W Twoim przykładzie kompilator jak widać najpierw ustala zawartość zmiennej a.a a później uruchamia funkcję a.b(). Sprawdziłem w moim systemie że g++ zachowuje się tak jak opisałeś (czyli niespodziewane 0) ale już clang++ nie :-)

Podziel swój kod tak jak to opisałeś i będzie działało na każdej platformie.

Tu masz jeszcze jedno takie zachowanie jako przykład. Rozważ co się będzie działo jeśli przetwarzanie będzie od lewej do prawej a co jak będzie odwrotnie.

int x = 12;
x = x++ + ++x;
std::cout << x << '\n';

Jaki twoim zdaniem powinien być x? Takie konstrukcje są po prostu niedopuszczalne :-)

3
komentarz 23 kwietnia 2017 przez adrian17 Ekspert (349,840 p.)

(AFAIK)

Czepialstwo: blisko, ale nie.

x++ + ++x

To jest UB, tak.

cout << a.b() << a.a;

To jest "tylko" unspecified. Przed/po wywołaniu metody są osobne sequence pointy (które, BTW, są zastąpione innymi regułami od c++11).

–2 głosów
odpowiedź 23 kwietnia 2017 przez Gankkah Użytkownik (720 p.)

Zmień definicję zmiennej 'a' na taką.

volalite int a;

P.S Na końcu definicji funkcji nie stawia się średnika!

1
komentarz 23 kwietnia 2017 przez unknown Nałogowiec (39,560 p.)
Raczej nic to nie pomoże.
komentarz 23 kwietnia 2017 przez rattle Użytkownik (510 p.)
Jak to nie. Stawia się jak mam samą deklaracje.

Ja chcę się dowiedzieć czemu takie rzeczy dziwne się dzieją, a nie chce nic zmieniać.

Bo normalnie to mi sie zawsze wydawało, że jak się wykona funkcja i coś zmieni to jest zmienione. No i tutaj niby jest zmienione ale dopiero w nastepnej linijce. A dlaczego nie w tej samej? skoro wypisane tego a.a następuje po wykonaniu funkcji to powinno już być "zaktualizowane" na 1.
2
komentarz 23 kwietnia 2017 przez adrian17 Ekspert (349,840 p.)
`volatile` ma zerowy związek z tym.

Chodzi po prostu o to, że w obecnej wersji języka kolejność "wykonywania" stron operatora jest nieokreślona. Nie można zakładać ani, że jest od lewej do prawej, ani że od prawej do lewej.

Tak więc najlepiej po prostu unikać takiego kodu.
komentarz 24 kwietnia 2017 przez Gankkah Użytkownik (720 p.)
edycja 25 kwietnia 2017 przez Gankkah
Gdy wstawimy tam 'volatile' to mówimy kompilatorowi żeby zawsze (!) sięgał do obiektu / zmiennej do szufladki.
komentarz 24 kwietnia 2017 przez rattle Użytkownik (510 p.)
w innym przypadku skąd sięga?
komentarz 25 kwietnia 2017 przez unknown Nałogowiec (39,560 p.)

volatile jest informacją dla kompilator, aby unikał dokonywania optymalizacji na zmiennej. 

w innym przypadku skąd sięga?

Kompilator w ramach optymalizacji może cache'ować zmienne

Podobne pytania

0 głosów
1 odpowiedź 621 wizyt
+2 głosów
2 odpowiedzi 861 wizyt
pytanie zadane 4 kwietnia 2016 w C i C++ przez caramelleandamour Użytkownik (550 p.)
0 głosów
2 odpowiedzi 298 wizyt

93,020 zapytań

141,982 odpowiedzi

321,283 komentarzy

62,366 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Wprowadzenie do ITsec, tom 2

Można już zamawiać tom 2 książki "Wprowadzenie do bezpieczeństwa IT" - będzie to około 650 stron wiedzy o ITsec (17 rozdziałów, 14 autorów, kolorowy druk).

Planowana premiera: 30.09.2024, zaś planowana wysyłka nastąpi w drugim tygodniu października 2024.

Warto preorderować, tym bardziej, iż mamy dla Was kod: pasja (użyjcie go w koszyku), dzięki któremu uzyskamy dodatkowe 15% zniżki! Dziękujemy zaprzyjaźnionej ekipie Sekuraka za kod dla naszej Społeczności!

...