Zakładając, że wskaźnik jest równoważny z liczbą całkowitą bez znaku, możemy zauważyć, że problem występuje tylko wtedy, gdy values
rozpoczęło się pod adresem 0, w którym to przypadku wskaźnik byłby zawijany po zmniejszeniu i stałby się UINT_MAX
.
Aby zobrazować problem, niech krok po kroku, co się dzieje, zakładając values
rozpoczyna się pod adresem 0x0:
iteration 1:
vp = 0x4, *vp = 0;
iteration 2:
vp = 0x3, *vp = 0;
iteration 3:
vp = 0x2, *vp = 0;
iteration 4:
vp = 0x1, *vp = 0;
iteration 5:
vp = 0x0, *vp = 0;
iteration 6:
vp = 0xFFFFFFFF; *vp = ?? // uh oh!
Zatem vp
nigdy nie będzie mniejsza od minimalnej wartości wskaźnika (czyli 0), oraz spowodowałoby to nieskończoną pętlę (zakładając, że cała pamięć jest zapisywalna) lub błąd segmentacji.
Jest to również niezdefiniowane zachowanie zgodne ze standardem (ponieważ można zaadresować jeden element za tablicą, ale nie przed nim), ale w rzeczywistości nie powinno to nigdy zawieść w żadnym realistycznym systemie.
to „niezdefiniowane”, ale na 95% systemów będzie dobrze. Scenariusz * jedyny *, w którym porównanie nie powiedzie się, będzie miał wartość 'i wartości [0]' == 0x0. –
Prawdopodobnie więcej niż 95%. =) –
Założę się, że nie działałoby to w implementacji C na Symbolics Lisp Machines. Nie mam pojęcia, czy nadal są jakieś w użyciu; firma wyszła z biznesu prawie 20 lat temu. – Barmar