//Questa forma è valida, anche se nella prima riga dopo il "type" TProvaRec non è stato ancora dichiarato e quindi dovrebbe
//essere formalmente un errore.
type
PProvaRec = ^TProvaRec;
TProvaRec = packed record
RefCnt: Integer;
Length: NativeInt;
end;
//Questa invece và giustamente in errore, ma sintaticamente dovrebbe essere identica a quella precedente ... invece evidentemente non lo è
//In ogni caso mi aspettavo che anche la forma precedente andasse in errore
type
PProvaRec = ^TProvaRec;
type
TProvaRec = packed record
RefCnt: Integer;
Length: NativeInt;
end;
Scusa, l'ho riguardato più volte, ma sembra lo stesso codice duplicato ... non vedo la differenza tra i 2 !!!La differenza è che mentre nel primo c'è un solo "type" nel secondo ce ne sono due.
The pointers to the data type can be used before they are declared. This is a forward declaration, an exception to the rule that things must be declared before they are used.
3.5 Dichiarazioni di tipo forward
I programmi spesso devono mantenere un elenco concatenato di record. Ogni record contiene quindi un puntatore al record successivo (e possibilmente anche al record precedente). Per la sicurezza dei tipi, è meglio definire questo puntatore come puntatore tipizzato, in modo che il record successivo possa essere allocato sull'heap utilizzando la chiamata New. Per fare ciò, il record dovrebbe essere definito in questo modo:
Type
TListItem = Record
Data : Integer;
Next : ^TListItem;
end;
Quando si tenta di compilare questo, il compilatore si lamenterà che il tipo TListItem non è ancora definito quando incontra la dichiarazione Next: Questo è corretto, poiché la definizione è ancora in fase di analisi.
Per poter avere l'elemento Next come puntatore tipizzato, è necessario introdurre una "dichiarazione di tipo forward":
Type
PListItem = ^TListItem;
TListItem = Record
Data : Integer;
Next : PTListItem;
end;
Quando il compilatore incontra una dichiarazione di puntatore tipizzata in cui il tipo referenziato non è ancora noto, rimanda la risoluzione del riferimento a un momento successivo. La definizione del puntatore è una "dichiarazione di tipo forward".
Il tipo referenziato dovrebbe essere introdotto in seguito nello stesso blocco Type. Nessun altro blocco può trovarsi tra la definizione del tipo puntatore e il tipo referenziato. Infatti, anche la parola Type stessa potrebbe non riapparire: in effetti avvierebbe un nuovo blocco di tipo, facendo sì che il compilatore risolva tutte le dichiarazioni in sospeso nel blocco corrente.
Nella maggior parte dei casi, la definizione del tipo referenziato seguirà immediatamente la definizione del tipo puntatore, come mostrato nell'elenco sopra. Il tipo definito forward può essere utilizzato in qualsiasi definizione di tipo successiva alla sua dichiarazione.
Nota che una dichiarazione di tipo forward è possibile solo con tipi e classi puntatore, non con altri tipi.
Mai usato la prima variante! Buono a sapersiNeanche io, e non ne vedo neanche una grossa utilità.
La differenza è che mentre nel primo c'è un solo "type" nel secondo ce ne sono due.
E nel secondo il compilatore si comporta come mi aspetto (cioè genera errore), mentre nel primo non dà errori.