* * * *

Privacy Policy

Blog italiano

Clicca qui se vuoi andare al blog italiano su Lazarus e il pascal.

Forum ufficiale

Se non siete riusciti a reperire l'informazione che cercavate nei nostri articoli o sul nostro forum vi consiglio di visitare il
Forum ufficiale di Lazarus in lingua inglese.

Lazarus 1.0

Trascinare un file nel programma
DB concetti fondamentali e ZeosLib
Recuperare codice HTML da pagina web
Mandare mail con Lazarus
Stabilire il sistema operativo
Esempio lista in pascal
File INI
Codice di attivazione
Realizzare programmi multilingua
Lavorare con le directory
Utilizzare Unità esterne
TTreeView
TTreeview e Menu
Generare controlli RUN-TIME
LazReport, PDF ed immagini
Intercettare tasti premuti
Ampliare Lazarus
Lazarus e la crittografia
System Tray con Lazarus
UIB: Unified Interbase
Il file: questo sconosciuto
Conferma di chiusura di un applicazione
Liste e puntatori
Overload di funzioni
Funzioni a parametri variabili
Proprietà
Conversione numerica
TImage su Form e Panel
Indy gestiore server FTP lato Client
PopUpMenu sotto Pulsante (TSpeedButton)
Direttiva $macro
Toolbar
Evidenziare voci TreeView
Visualizzare un file Html esterno
StatusBar - aggirare l'errore variabile duplicata
Da DataSource a Excel
Le permutazioni
Brute force
Indy 10 - Invio email con allegati
La gestione degli errori in Lazarus
Pascal Script
Linux + Zeos + Firebird
Dataset virtuale
Overload di operatori
Lavorare con file in formato JSON con Lazarus
Zeos ... dietro le quinte (prima parte)
Disporre le finestre in un blocco unico (come Delphi)
Aspetto retrò (Cmd Line)
Lazarus 1.0
Come interfacciare periferica twain
Ubuntu - aggiornare free pascal e lazarus
fpcup: installazioni parallele di lazarus e fpc
Free Pascal e Lazarus sul Raspberry Pi
Cifratura: breve guida all'uso dell'algoritmo BlowFish con lazarus e free pascal.
Creare un server multithread
guida all'installazione di fpc trunk da subversion in linux gentoo
Indice
DB concetti fondamentali e connessioni standard
Advanced Record Syntax
DB concetti fondamentali e DBGrid
DB concetti fondamentali e TDBEdit, TDBMemo e TDBText
Advanced Record Syntax: un esempio pratico
Superclasse form base per programmi gestionali (e non)
Superclasse form base per programmi gestionali (e non) #2 - log, exception call stack, application toolbox
Superclasse form base per programmi gestionali (e non) #3 - traduzione delle form
Superclasse form base per programmi gestionali (e non) #4 - wait animation
Un dialog per la connessione al database:TfmSimpleDbConnectionDialog
Installare lazarus su mac osx sierra
immagine docker per lavorare con lazarus e free pascal
TDD o Test-Driven Development
Benvenuto! Effettua l'accesso oppure registrati.
Novembre 23, 2024, 01:52:43 pm

Inserisci il nome utente, la password e la durata della sessione.

43 Visitatori, 0 Utenti

Autore Topic: Sintassi pascal  (Letto 68 volte)

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1399
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Sintassi pascal
« il: Novembre 22, 2024, 11:44:36 pm »
Ciao a tutti.

faccio una domanda che sarà magari stupida ma è curioso il comportamento:
- per quale motivo queste due "scritture" differiscono ?

In particolare, perchè la prima non genera errore ?

Codice: [Seleziona]
//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;

Codice: [Seleziona]
//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;

:) Ogni alba è un regalo, ogni tramonto è una conquista :)

bonmario

  • Hero Member
  • *****
  • Post: 1360
  • Karma: +11/-1
Re:Sintassi pascal
« Risposta #1 il: Oggi alle 07:20:11 am »
Scusa, l'ho riguardato più volte, ma sembra lo stesso codice duplicato ... non vedo la differenza tra i 2 !!!

Ciao, Mario

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1399
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:Sintassi pascal
« Risposta #2 il: Oggi alle 08:21:47 am »
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.

E nel secondo il compilatore si comporta come mi aspetto (cioè genera errore), mentre nel primo non dà errori.

Anche su Delphi è così, quindi ritengo che ovviamente sia giusto così.
Volevo sapere il perchè (evidentemente ha a che fare con i construtti del linguaggio).

Da una nota relativa alla definizione del Pascal:
Citazione
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.

Però non giustifica il fatto che nel caso sopra sia usabile e in quello sotto no.
Devo approfondire
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1399
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:Sintassi pascal
« Risposta #3 il: Oggi alle 08:26:32 am »
Ecco spiegato l'arcano: https://www.freepascal.org/docs-html/ref/refse16.html

Traduco in Italiano:

Citazione
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.

In pratica il compilatore quando il "blocco" in cui il type termina DEVE risolvere tutte le "definizioni" rimaste in piedi (come negli esempi). Quindi nel primo caso la sintassi è corretta, nel secondo invece no in quanto il secondo type "chiude" il blocco precedente senza definire il "tipo" puntato.

Ehhh se ne impara sempre una. Non sapevo neanche fosse possibile una "forward declaration" in Pascal ... ???

Il tutto è scaturito da un wrapper che ho generato di qualche decina di migliaia di righe e in alcuni punti avevo questo errore apparentemente senza senso, mentre in altri simili no.
« Ultima modifica: Oggi alle 08:39:05 am da DragoRosso »
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

xinyiman

  • Administrator
  • Hero Member
  • *****
  • Post: 3274
  • Karma: +12/-0
Re:Sintassi pascal
« Risposta #4 il: Oggi alle 09:26:32 am »
Mai usato la prima variante! Buono a sapersi
Ieri è passato, domani è futuro, oggi è un dono...

DragoRosso

  • Scrittore
  • Hero Member
  • *****
  • Post: 1399
  • Karma: +44/-0
  • Prima ascoltare, poi decidere
Re:Sintassi pascal
« Risposta #5 il: Oggi alle 09:31:01 am »
Mai usato la prima variante! Buono a sapersi
Neanche io, e non ne vedo neanche una grossa utilità.
Normalmente il puntatore ad un nuovo tipo viene definito dopo la definizione del tipo, in stile C.

Buona giornata
:) Ogni alba è un regalo, ogni tramonto è una conquista :)

bonmario

  • Hero Member
  • *****
  • Post: 1360
  • Karma: +11/-1
Re:Sintassi pascal
« Risposta #6 il: Oggi alle 10:52:24 am »
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.

Ah, grazie, non me ne ero nemmeno accorto !!!
Tra l'altro,m per abitudine ormai consolidata nel tempo, indipendentemente dal linguaggio di programmazione usato, tendo a dichiarare sempre prima quello che userò, anche se non è necessario ... nel tempo ho notato che in ogni caso mi aiuta a fare meno errori

Ciao, Mario

 

Recenti

How To

Utenti
  • Utenti in totale: 803
  • Latest: maXim.FI
Stats
  • Post in totale: 19176
  • Topic in totale: 2287
  • Online Today: 102
  • Online Ever: 900
  • (Gennaio 21, 2020, 08:17:49 pm)
Utenti Online
Users: 0
Guests: 43
Total: 43

Disclaimer:

Questo blog non rappresenta una testata giornalistica poiché viene aggiornato senza alcuna periodicità. Non può pertanto considerarsi un prodotto editoriale ai sensi della legge n. 62/2001.