auto a = new int[0];
Zgodnie z [basic.compound.3] przechowywana wartość a
musi być jedną z następujących czynności:
- Wskaźnik do obiektu (typu
int
)
- Wskaźnik za końcem obiektu
- Zero
- Nieważny
Możemy wykluczyć pierwszą możliwość, ponieważ nie zbudowano żadnych obiektów typu int
. Trzecia możliwość jest wykluczona, ponieważ C ++ wymaga zwrotu niepustego wskaźnika (patrz [basic.stc.dynamic.allocation.2] ). Mamy zatem dwie możliwości: wskaźnik za końcem obiektu lub nieprawidłowy wskaźnik.
Byłbym skłonny postrzegać a
jako wskaźnik przeszłości, ale nie mam renomowanego odniesienia, aby definitywnie to ustalić. (Istnieje jednak silna implikacja tego w [basic.stc] , widząc, jak można delete
ten wskaźnik.) W związku z tym przedstawię obie możliwości.
Czy między inicjowaniem i usuwaniem kopii można odczytywać wskaźnik w a + 1
?
Zachowanie jest niezdefiniowane, jak podyktowane jest to [expr.add.4] , niezależnie od tego, która z powyższych możliwości ma zastosowanie.
Jeśli a
wskaźnik jest końcowy, uważa się, że wskazuje hipotetyczny element na indeks 0
tablicy bez elementów. Dodanie liczby całkowitej j
do a
jest definiowane tylko wtedy 0≤0+j≤n
, gdy , gdzie n
jest rozmiar tablicy. W naszym przypadku n
wynosi zero, więc suma a+j
jest definiowana tylko wtedy, gdy j
jest 0
. W szczególności dodawanie 1
jest niezdefiniowane.
Jeśli a
jest nieważny, wówczas czysto popadamy w „W przeciwnym razie zachowanie jest niezdefiniowane”. (Nic dziwnego, że zdefiniowane przypadki obejmują tylko prawidłowe wartości wskaźnika).
Ponadto, nie pozwalają na język kompilator zestaw a
do nullptr
?
Nie. Z wyżej wspomnianego [basic.stc.dynamic.allocation.2] : „Jeśli żądanie powiedzie się, wartość zwrócona przez wymienną funkcję alokacji jest wartością wskaźnika o wartości innej niż zero” . Istnieje również przypis wzywający, że C ++ (ale nie C) wymaga niepustego wskaźnika w odpowiedzi na żądanie zerowe.
a
na pewno czytać (z pewnością nie możesz tego wyrejestrować).