Confusione su tipi di dati, compilatori, rappresentazione dei dati hardware e tipizzazione statica e dinamica [chiusa]

0

Sto cercando di capire la digitazione statica rispetto alla dinamica, ma sto davvero cercando di capire come tutto combaci.

Tutto inizia con i tipi di dati. Per quanto ho capito, i tipi di dati sono nozioni abbastanza astratte, che esistono nei compilatori 'in' per classificare i dati in modo che le operazioni su vari tipi di dati possano essere validate (cioè nel tentativo di interrompere l'aggiunta di una stringa a un intero ), e per generare il codice macchina corretto per l'interpretazione hardware del valore. Cioè diciamo di avere il seguente:

int myInt = 5;
char myChar = '5';

Console.WriteLine(myInt);
Console.WriteLine(myChar);

Entrambi alla fine scriveranno un cinque nella finestra della console, ma, poiché le rappresentazioni in memoria di numeri interi e caratteri sono differenti, il codice macchina che interpreta il valore nella posizione di memoria associata alla variabile myInt, che prende quel valore e lo visualizza sulla finestra della console, sarebbe diverso dal codice macchina per myChar. Anche se Console.WriteLine () "fa lo stesso lavoro", le diverse rappresentazioni di cinque richiedono un codice di basso livello diverso.

Quindi la mia domanda è questa: se i tipi di dati 'esistono solo nel compilatore' - cioè una volta che il programma è stato compilato nel codice macchina non si ha conoscenza di quale tipo di dati il valore in una particolare cella di memoria è (tutto è solo 1s e 0s) - allora come può essere eseguito un controllo dei tipi in fase di esecuzione? Sicuramente non esiste un concetto di tipi di dati in fase di esecuzione? Quindi sicuramente la digitazione dinamica non può avere nulla a che fare con il controllo dei tipi che si verifica in fase di esecuzione?

Dove la mia comprensione sta andando male, e qualcuno potrebbe spiegare la tipizzazione statica e dinamica rispetto all'argomento sopra riportato? Qual è il quadro generale di ciò che sta succedendo?

Sto cercando di capire questo per un saggio, quindi i riferimenti a libri o fonti online sarebbero utili :) Grazie.

    
posta Lord Cat 28.11.2015 - 19:21
fonte

5 risposte

1

La tua affermazione che "i tipi di dati esistono solo nel compilatore" non è vera per i linguaggi dinamici (e non alcuni quelli statici).

Una volta che non regge, diventa un semplice controllo di runtime.

    
risposta data 28.11.2015 - 19:56
fonte
0

How can any type-checking be done at runtime? Surely there is no concept of data types at run time?

A volte ci sono sono tipi di dati in fase di runtime. Altre volte, il controllo del tipo può essere eseguito interamente in fase di compilazione. In linea di principio, dipende dall'implementazione se sceglie di implementare un controllo di tipo in fase di compilazione o in fase di esecuzione e hanno molte opzioni.

In linguaggi come C ++ e Java, esiste una distinzione tra tipi primitivi (tipicamente interi, caratteri, ecc.) e tipi strutturati o complessi (tipicamente structs e classes). In questi linguaggi è comune per solo i tipi strutturati conservare alcuni metadati relativi al loro tipo in fase di esecuzione (sebbene di solito includano i tipi dei loro campi / membri primitivi). Ad esempio, in C ++, la funzione typeid viene in genere valutata al momento della compilazione e funziona anche su tipi primitivi, mentre una dynamic_cast viene eseguita in fase di runtime e funziona solo sulle classi.

In linguaggi più dinamici come Python e Javascript, qualsiasi variabile può avere qualsiasi tipo, quindi un interprete semplice probabilmente dovrà implementare tutte le variabili come un "tipo di variante", cioè una classe che porta letteralmente il proprio tipo attorno . Un'interpretazione più sofisticata può utilizzare l'ottimizzazione dei compilatori AOT o JIT che vengono eseguiti su sezioni di codice in cui tutti i problemi di digitazione possono essere dimostrati in fase di compilazione, quindi è sicuro sostituire i tipi di varianti e il loro controllo di runtime con codice altamente ottimizzato. Questo è il motivo per cui vedi articoli sulle "classi interne" del motore Javascript V8 che ti dicono di evitare di modificare dinamicamente la struttura dei tuoi oggetti o dei tipi memorizzati nei tuoi array, perché quel genere di cose impedisce a V8 di ottimizzarlo su "solo 1s" e "0" che non conoscono i propri tipi.

Speriamo che questi esempi siano sufficienti a chiarire la tua confusione.

    
risposta data 28.11.2015 - 20:02
fonte
0

Potresti pensare che

Console.WriteLine(myInt);
Console.WriteLine(myChar);

vengono compilati allo stesso modo. Ma molto probabilmente la compilazione viene compilata per qualcosa di simile

Console.WriteInteger(myInt);
Console.WriteEndOfLine();
Console.WriteChar(myChar);
Console.WriteEndOfLine();

D'altra parte, alcune lingue sono molto flessibili. Ad esempio, Swift ha il tipo di dati Qualsiasi che può letteralmente contenere qualsiasi valore. Un oggetto Any è abbastanza grande, perché contiene non solo il valore, ma una descrizione completa del valore. Se scrivi

var myInt:Any = 5
var myChar:Any = '5'

allora hai due oggetti di tipo Any, uno contenente la descrizione del tipo "Int" e un valore intero, uno contenente la descrizione del tipo "Char" e un valore char.

    
risposta data 28.11.2015 - 20:43
fonte
0

Dipende dalla lingua. In C, i tipi esistono solo al momento della compilazione. In Java e C #, i tipi esistono sia in fase di compilazione che in fase di esecuzione. Nei linguaggi dinamici (come Python, JavaScript ecc.) Esistono solo in fase di esecuzione.

Il tuo esempio di codice funzionerebbe quindi in modo diverso a seconda della lingua. In Java / C # le due chiamate a Console.WriteLine() chiamano in realtà due metodi diversi. Questo è chiamato overloading di metodi: più metodi possono avere lo stesso nome, purché abbiano tipi diversi di parametri, quindi il compilatore può selezionare l'implementazione del metodo corretta in fase di compilazione a seconda dei tipi degli argomenti. I due diversi metodi si verificano solo per produrre lo stesso risultato in questo caso specifico.

Un linguaggio dinamico d'altra parte non avrebbe sovraccarico di metodo, ma potrebbe avere un singolo metodo che si comporta diversamente a seconda del tipo di runtime dell'argomento.

    
risposta data 28.11.2015 - 21:22
fonte
-3

Dipende interamente dal runtime. Java lo fa in un modo, .NET ne fa un altro, Python fa un terzo modo, il C ++ lo fa in modo limitato e C non lo fa affatto.

Tali informazioni sul tipo di runtime potrebbero venire o come metadati (o un puntatore a esso) associate a un oggetto, o essere invece informazioni di tipo statico mascherate da informazioni di tipo dinamico (ad esempio C ++ typeid operatore). Ma, ancora, dipende dal runtime.

    
risposta data 28.11.2015 - 19:43
fonte