Proprietà di un puntatore a un array di lunghezza zero


21

Prendere in considerazione

int main()
{
    auto a = new int[0];
    delete[] a; // So there's no memory leak
}

Tra l'inizializzazione e la cancellazione della copia, è consentito leggere il puntatore su a + 1?

Inoltre, non il linguaggio permette al compilatore di serie aa nullptr?


2
@Fareanor: puoi leggere acon certezza (non puoi certo dereferenziarlo).
Bathsheba,

8
@RasmiRanjanNayak: Questo è hogwash.
Bathsheba,

2
@RasmiRanjanNayak Oh mio ... no
Ted Lyngmo,

1
@TedLyngmo: quando dico "leggi il puntatore a a + 1", il codice seguente è un auto b = a + 1;comportamento indefinito? (Penso che sia).
Bathsheba,

2
@Ayxan Immagino che nel caso in cui 0sia effettivamente il risultato di qualche espressione che non conoscerai fino al runtime. Dal momento che new int[0]è sicuro, potrebbe farti preoccupare di alcune ramificazioni / casi speciali. Immagina se dovessi inizializzare un std::vectorcon std::vector<int> v(0);.
scohe001,

Risposte:


3
    auto a = new int[0];

Secondo [basic.compound.3] , il valore memorizzato in adeve essere uno dei seguenti:

  1. Un puntatore a un oggetto (di tipo int)
  2. Un puntatore oltre la fine di un oggetto
  3. Nullo
  4. Non valido

Possiamo escludere la prima possibilità poiché non sono stati intcostruiti oggetti di tipo . La terza possibilità è esclusa poiché C ++ richiede la restituzione di un puntatore non nullo (vedere [basic.stc.dynamic.allocation.2] ). Quindi ci rimangono due possibilità: un puntatore oltre la fine di un oggetto o un puntatore non valido.

Sarei propenso a vederlo acome un puntatore del passato, ma non ho un riferimento affidabile per affermarlo definitivamente. (Vi è, tuttavia, una forte implicazione di ciò in [basic.stc] , vedendo come è possibile deletequesto puntatore.) Quindi intratterrò entrambe le possibilità in questa risposta.

Tra l'inizializzazione e la cancellazione della copia, è consentito leggere il puntatore su a + 1?

Il comportamento non è definito, come dettato da [expr.add.4] , indipendentemente da quale possibilità si applichi sopra.

Se aè un puntatore passato, allora si considera che punti all'ipotetico elemento all'indice 0di un array senza elementi. L'aggiunta del numero intero ja aviene definita solo quando 0≤0+j≤n, dov'è nla dimensione dell'array. Nel nostro caso, nè zero, quindi la somma a+jviene definita solo quando lo jè 0. In particolare, l'aggiunta 1non è definita.

Se anon è valido, cadiamo chiaramente in "Altrimenti, il comportamento non è definito." (Non sorprende che i casi definiti coprano solo valori di puntatore validi.)

Inoltre, non il linguaggio permette al compilatore di serie aa nullptr?

No. Dal summenzionato [basic.stc.dynamic.allocation.2] : "Se la richiesta ha esito positivo, il valore restituito da una funzione di allocazione sostituibile è un valore puntatore non nullo" . C'è anche una nota a piè di pagina che afferma che C ++ (ma non C) richiede un puntatore non nullo in risposta a una richiesta zero.


1
Se fosse un valore di puntatore non valido, avrai seri problemi da eel.is/c++draft/basic.stc#4
TC

@TC True, ciò implica fortemente che non può essere un valore di puntatore non valido.
JaMiT

23

Secondo una recente discussione sul riflettore CWG a seguito del numero editoriale 3178 , new int[0]produce quello che attualmente viene chiamato un valore puntatore "passato alla fine" .

Ne consegue che anon può essere nullo e a + 1non è definito da [expr.add] / 4 .


4
"Secondo una recente discussione sul riflettore CWG a seguito del numero editoriale 3178, new int[0]produce quello che attualmente viene chiamato un valore di puntatore" passato alla fine "" Questo non è accurato. Non c'erano molte discussioni. Una persona ha suggerito che il valore dovrebbe essere "puntatore oltre la fine di un oggetto", e questa affermazione è stata messa in discussione perché nel caso di un array con 0elementi, non c'è alcun oggetto oltre la fine.
Avvocato linguistico

@LanguageLawyer non sembra esserci alcun dubbio che a + 1non sia definito in ogni caso, quindi il tuo punto riguarda solo se apuò essere nullo?
MM

Non sembra esserci alcun disaccordo sulla semantica prevista, né che il nome corrente per questa categoria di valori del puntatore non sia adatto a questo scenario.
TC

@MM Penso che a + 1sia indefinito e forse il valore del puntatore risultante verrà chiamato "puntatore oltre la fine". Non sto dicendo che la risposta sia sbagliata. Non è leggermente accurato perché potrebbe essere inteso come se ci fosse una lunga discussione con un consenso sul fatto che la semplice precisazione che il risultato è "puntatore oltre la fine" è sufficiente per risolvere il problema. Il problema con "puntatore oltre la fine" è che è oltre la fine di alcuni oggetti e la sottrazione 1da un tale valore di puntatore dà un puntatore all'oggetto, che probabilmente non dovrebbe essere il caso di matrici di 0elementi.
Avvocato linguistico il

2
@Bathsheba Pensi che ci potrebbe essere qualcosa di più autorevole nella formulazione difettosa?
Avvocato linguistico
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.