Dimentichiamo per il momento che i processori hanno hardware specifico per manipolare sequenze di byte di una particolare dimensione. Dimentichiamo per il momento che i processori hanno hardware specifico per operare su specifiche interpretazioni di sequenze di byte (registri a virgola mobile, registri SEE, ecc.).
A che serve questa astrazione dal punto di vista dell'utente? Dopo tutto, il linguaggio di programmazione esiste per la comodità del programmatore. Se l'astrazione non sta facendo qualcosa di utile per il programmatore, allora l'astrazione potrebbe anche non esserci.
Quindi l'unico tipo fondamentale fornito dalla lingua è un byte. E quindi ogni altro tipo è una forma di sequenza di byte. OK.
Non vogliamo che programmatori diversi dichiarino forme diverse dello stesso tipo come float
o int32
o altro. Dopotutto, il float a 4 byte di una persona non sarebbe interoperabile con il float di 4 byte di qualcun altro. Non solo, diversi programmatori sprecheranno molto tempo ad implementare la stessa cosa.
Quindi la libreria standard per un tale linguaggio non avrebbe altra scelta che includere sequenze e operazioni generalmente utili su di essi. Ci sarebbe un equivalente di float
, double
, int
, ecc.
Quindi, che cosa hai ottenuto rispetto a quando questi tipi di lingue sono stati forniti? Devi comunque fornirli, in ogni caso.
I linguaggi di programmazione (che non sono assemblaggio e persino assemblaggio in una certa misura) esistono per fornire utili astrazioni all'utente. Consentono all'utente di programmare un modello astratto piuttosto che i capricci specifici di un sistema, consentendo al compilatore di eseguire il lavoro meccanico di traduzione del modello astratto in un sistema reale.
Tuttavia, un modello astratto può talvolta intralciare trasformazioni ottimali. A volte, è perché il modello astratto definisce troppo. Ad esempio, Java definisce praticamente tutto ciò che riguarda i suoi tipi di base. float
è garantito come valore in virgola mobile a 32 bit IEEE-754. Il che significa che se vuoi eseguire un programma Java su una piattaforma che non ha il supporto IEEE-754 nell'hardware, devi emulare il codice matematico in virgola mobile.
Per contro, C / C ++ non dice nulla su cosa float
fornisce oltre al fatto che può avere valori che non sono numeri interi. In quanto tale, un compilatore per l'hardware che non ha il supporto IEEE-754 potrebbe convertire le operazioni float
in una forma di matematica a virgola fissa. Oppure fai qualcosa di insolito, ma qualcosa di più veloce dell'emulazione software di IEEE-754.
Il tuo modello astratto fallisce nell'altra direzione. Specifica così poco che in realtà è sottostimato rispetto all'hardware, rendendo così più difficile la conversione in operazioni hardware. L'hardware può agire a livello di byte, ma le CPU effettive operano a livello di registro: gruppi di byte con un significato particolare. Esistono anche diversi tipi di registri con diversi tipi di operazioni su di essi.
Considera cosa succede se il tuo sistema di array di bit è basato su byte a 8 bit, e poi lo porti su un sistema in cui la CPU usa 9 bit byte (e sì, è così una cosa reale). C e C ++ supportano tali sistemi, proprio perché non specificano le cose a livello di bit. Un int
potrebbe essere un oggetto a 4 byte, ma sarebbe di 36 bit. Il tuo int32
sarebbe inutile su tale sistema, in quanto l'hardware non può supportarlo in modo efficace.
Trovare la giusta astrazione per alte prestazioni, una che è abbastanza alta per essere un'astrazione utile per il programmatore, abbastanza alta da coprire un sacco di hardware, ma abbastanza bassa da non intralciare il programmatore, è molto difficile lavoro.