Problem jest taki, mamy taki niewinny kod:
#include
int get_val(const int **pp)
{
return **pp;
}
int main()
{
int v = 10;
int *t[] = { &v };
printf("%i\n", get_val(t) );
}
Kompilator w linii z printf zgłasza błąd ? Dlaczego, przecież nie robię nic złego :). Deklaruje tablice wskaźników do int o wielkości jednego elementu (jeden wskaźnik), i chce go przekazać wskaźnik do tej tablicy do funkcji która zwraca wartość; Funkcja nie modyfikuje zawartości elementów wiec dodajemy const, tak dla zasady :) (bo w firmie wymagają żeby dawać const)
Poniższa strona nie za bardzo mnie przekonała:
http://www.parashift.com/c++-faq-lite/const-correctness.html#faq-18.17
Wolałem sobie to wytłumaczyć następująco:
#include
const v = 0;
const int *p = &v;
int get_val(const int **pp)
{
*pp = p;
return **pp;
}
int main()
{
int v = 10;
int *t[] = { &v };
//printf("%i\n", get_val(t) );
*(t[0]) = 20; //tutaj teoretycznie modyfikujemy lokalna zmienna, a tak naprawdę funkcja podmieniła wskaźnik i modyfikujemy const ... otrzymujemy SIGSEG
printf("%i\n", v );
}
Teraz ewidentnie widać dlaczego rzutowanie int ** na const int ** jest zabronione :)
Bład w stwierdzeniu jest następujący:
Deklaruje tablice wskaźników do int o wielkości jednego elementu (jeden wskaźnik), i chce go przekazać wskaźnik do tej tablicy do funkcji która zwraca wartość. Funkcja nie modyfikuje zawartości elementów ALE MOŻNE MODYFIKOWAĆ ZAWARTOŚĆ TABLICY :), w szczególności podmienić wskaźnik na coś czego zmieniać nie wolno (a co jest poprawnym adresem procesu).
PS: A mówią ze stałe wskaźniki są niepopularne
PS2: Teraz już wiem gdzie są wykorzystywane :P. Wykorzystywane są do męczenia biednych developerów :D
PS3: Wymiękam ... dlaczego poniższe jest problemem ? HELP!!!
int main()
{
int v;
int * const p = &v;
const * const **pp = &p;
}
Brak komentarzy:
Prześlij komentarz