Zdjecie przydomka const ze wskaznika

0

Witam! Mam problem w zrozumieniu pewnej rzeczy:

const int a = 5;
const * wsk = &a;
int * wsk2 = const_cast<int *>(wsk);
*wsk2 = 10;
cout<<a; 

czyli ściągam z wsk przydomek const i ustawiam adres na wsk2, czyli wszedzie mam teraz ten sam adres? i jak modyfikuje wsk2 ( bo ściągnąłem castem) to wartosc na a tez się powinna modyfikować?

3

To jest undefined behavior. Nie można modyfikować czegoś, co jest const nawet, jeżeli "usunęło" się const za pomocą const_cast. Ten operator do tego nie służy.

Uprzedzając pytanie: const_cast służy głównie do łączenia nowego kodu z jakimś starym kodem C, który nie jest const correct. Można to jednak zrobić tylko, kiedy wiadomo, że ten kod nie modyfikuje danej zmiennej, która była const, a po prostu ma zły interfejs. Jest jeszcze jakieś szemrane zastosowanie ze zdejmowaniem volatile i synchronizacją wątków ale nie zajmowałem się tym zbytnio.

3

To co zrobiłeś to UB, bo nie masz prawa modyfikować wartości będącej faktycznie const (możesz tylko jeśli const zostało dodane gdzieś w łańcuchu wywołań).

2
int a=5;
const int * wsk=&a;
int *wsk2=const_cast<int*>(wsk);
*wsk2=10;
cout<<a;

To ma jakiś tam sens.

1

jest jeszcze jakieś szemrane zastosowanie ze zdejmowaniem volatile

za pomocą const_cast można:

  • nic nie robić
  • zdjąć lub dodać const
  • zdjąć lub dodać volatile
  • zamienić const na volatile i odwrotnie

możliwe są więc wszelkie konwersje w obrębie T*, const T*, volatile T* i const volatile T*

ale nie służy to do takiego oszukiwania że mamy zmienną zdefiniowaną const int i chcemy się mimo wszystko do niej dobrać.

0

Po pierwsze to chyba masz problem z typami, bo wsk nie ma typu :p. Po drugie, jedyny sposób na ściągnięcie consta to przekopiowanie wartości i działanie na kopii. Inaczej prosisz się o kataklizm. ;) Przecież po coś ten const został nałożony na tą zmienną. Zywkle po to, żeby zagwarantować poprawność programu. :)

0

poza przypadkiem opisanym przez @Endrju mi się przydarzył inny przypadek, kiedy const_cast.
Robiłem lazy evaluation, więc geter, który był const wykonywał obliczenia a następnie je zapamiętywał, więc można było rozwiązać na dwa soposby: const_cast by zmienić wartość pola obiektu z tą wartością, albo uczynienie tego pola mutable (ja wybrałem tą opcję).

W dobrze pisanym kodzie prawdopodobieństwo użycia const_cast jest bardzo, ale to bardzo nikłe. Dopóki nie robisz jakiś dziwniejszych rzeczy nie jest ci to potrzebne.

0

Ale nie chodziło mi czy jest to poprawnie....tylko o to czy z tym kodem cout<< a; powinno wypisać w takim przypadku 10? czy wlaśnie nie zmieni tej wartości....

3

Jak nie jest poprawnie, to w jaki sposób możesz czynić jakiekolwiek założenia wobec tego kodu? UB jest jak dzielenie przez zero w matematyce - od tego momentu wynik działania jest dowolny.
user image

4

Trudno powiedzieć co z tym zrobi kompilator. Są trzy możliwości:

  1. kompilator uzna to za stałą znaną podczas kompilacji i kod nawet nie będzie się odnosił do zmiennej w której jest ta stała, tylko po prostu zawsze do cout wyśle wartość 5. (wynik 5)
  2. kompilator jednak wygeneruje kod, który odniesie się do zmiennej, a zmienną umieści w takim miejscu, że system pozwoli na zmianę wartości (wynik 10)
  3. kompilator jednak wygeneruje kod, który odniesie się do zmiennej, a zmienną umieści w takim miejscu, że twój program będzie mógł ją tylko odczytać, więc próba zapisu zakończy się sygnałem SIGSEG.
    Dlatego właśnie masz UB (undefined behevior)
    Te trzy sytuacje zależą od kompilatora, systemu, a nawet kontekstu w jakim użyjesz tego kodu, a nawet od wielkości strony na danym komputerze.
0

no i oto mi chodzilo....bo w jednej sytuacji kompilator zaśpiewał 10, a w drugiej 5 :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1