W pewnych założeniach w C Trzeci wiersz:
int* two = (int*)((char*)p + 7);
już powoduje nieokreśloną problem, ponieważ wskaźnik p nie jest prawidłowo wyrównana w rodzaju nie odwołuje .
Zakłada się, że wymagania osiowania dla typu int są wyższe niż dla typu char. Dotyczy to większości współczesnych architektur. Ponieważ wszystkie linie trasowania muszą być potęgami dwóch: , a wartość 7 nie jest, dodanie tej wartości do wskaźnika p nie może wytworzyć wskaźnika z wyrównaniem, które jest tak ścisłe jak wymaganie wyrównania dla typu int.
(Cyt z ISO/IEC 9899: 201X 6.3.2.3 Wskaźniki 7)
wskaźnik do typu obiekt może być przekształcany do wskaźnika na inny typ obiektu. Jeśli wskaźnik wynikowy nie jest poprawnie wyrównany dla typu odniesienia, zachowanie jest nieokreślone jako .
(Cytat z: ISO/IEC 9899: 201x 6.2.8 Dostosowanie obiektów 4.)
Każda ważna wartość wyrównanie będzie nieujemną integralną potęgą dwójki.
Wywołałeś * niezdefiniowane zachowanie * przekazując dane o błędnym typie do 'printf()'. Poprawną instrukcją do wydrukowania będzie 'printf ("% p% p% zu% td \ n ", (void *) jeden, (void *) dwa, sizeof (int), dwa - jeden);' – MikeCAT
Nie mam cytuj. Arytmetyka wskaźnikowa opiera się na arytmetyce całkowitej i jest dobrze zdefiniowana. Myślę więc, że "dwa - jeden" jest dobrze zdefiniowany. nawet jeśli wskaźniki nie są zapakowane tak, jak można by oczekiwać rozsądnej osoby. Z drugiej strony - nie rób tego, nikt nie zauważy tego w twojej bazie kodów. – Johannes
Nawet samo trzymanie wskaźnika "dwa" w twoim programie jest niepoprawne, ponieważ wskaźnik nie spełnia ograniczeń wyrównania dla 'int' (chociaż w praktyce na większości sprzętu nie wywoła błędu, dopóki faktycznie nie spróbujesz go usunąć procesor, który nie koryguje braku dostępu do pamięci jak ARM) – Thomas