Cosa impedisce a C di essere compilato / interpretato / JIT?


9

Java è spesso elogiato per la sua straordinaria portabilità, che presumo sia dovuta alla JVM. La mia domanda è cosa impedisce a C di essere compilato / interpretato / JIT .., in tal caso, C può anche essere scritto una volta e farlo funzionare su qualunque dispositivo tu abbia. ma questo non è un meccanismo popolare per l'elaborazione di un programma C.

Quali sono gli svantaggi dell'elaborazione di C in questo modo, anche quali sono i vantaggi dell'elaborazione di Java in questo modo e della non compilazione in codice macchina, a parte la portabilità ovviamente?


La tua domanda ha già delle ottime risposte qui: stackoverflow.com/questions/3925947/…
Doc Brown

2
@delnan il mio punto è che "ciò che impedisce a C di essere compilato / interpretato / JIT" perde davvero il suo significato quando il linguaggio può scegliere come target una macchina virtuale con JIT o situazioni in cui la VM identificherà le funzioni mancanti nell'hardware e ricompilerà il codice per abbinare l'hardware esistente (come con OpenGL (scritto in C) su OSX per diverse schede grafiche). No, non puoi prendere qualcosa compilato per indirizzare llvm su una macchina ed eseguirlo come tale su un altro processore. Ma la riga compilata / interpretata / JIT può essere piuttosto sfocata.

1
Java è spesso pubblicizzato per la sua straordinaria portabilità. È portabile su sistemi in cui è stata compilata la JVM, vale a dire sistemi per i quali è stata compilata la JVM (scritta in C). Non c'è nulla che impedisca la gestione del codice C allo stesso modo, tranne che nessuno vede abbastanza benefici nel farlo per giustificare lo sforzo.
Pete Becker,

2
Sono perplesso su questo bit: "cosa impedisce a C di essere compilato / [...]". Uh, niente?
Andres F.

1
I compilatori C sono piuttosto veloci in questi giorni, quindi "make myprog.c; myprog" probabilmente funzionerà più velocemente della maggior parte degli interpreti.
James Anderson,

Risposte:


18

C è quella che definirei una lingua di medio livello. Il suo scopo è quello di fungere da "assemblatore di altissimo livello", motivo per cui funziona così bene come obiettivo del compilatore e perché abbraccia così bene la portabilità.

Storicamente, gli interpreti sono stati generalmente utilizzati con linguaggi di alto livello, nel contesto delle chiamate di metodo. Nella sua forma più semplice, un interprete analizza semplicemente ogni parola chiave nella lingua di origine insieme ai token associati e la converte in chiamate e parametri di metodo. In pratica, ciò che la maggior parte degli interpreti fa è convertire la lingua di origine in una rappresentazione intermedia, ed è quella rappresentazione che viene interpretata.

Cosa impedisce a C di essere interpretato o Jitted? Niente. Ma questa non è la ragion d'essere di C.


6

Prima di tutto, vale la pena notare che la JVM di Sun è stata scritta in C. C è un linguaggio molto popolare quando è necessaria la portabilità.

Il linguaggio C è portatile anche se molti programmi C non lo sono. Questo perché C non pone così tante restrizioni al programmatore né fa altrettante ipotesi. Se un programmatore C vuole che i suoi programmi siano portatili, deve imporre queste restrizioni su se stesso.

In pratica, non è molto più difficile che vivere con le restrizioni che Java ti impone. Si tratta principalmente di essere consapevoli della tua endianness e dimensioni primitive e di utilizzare librerie portatili come GTK + invece di librerie specifiche della piattaforma.

Potresti creare un target GTK + e un compilatore C che supportasse una macchina virtuale, anche probabilmente la JVM, e far funzionare il codice esistente con pochissime modifiche. In effetti, senza la garbage collection, una macchina virtuale C sarebbe probabilmente molto più semplice. Perché dovresti volerlo, però?

È anche possibile fare il contrario, compilando Java in codice nativo. Questo è fondamentalmente ciò che la JIT fa. Perché dovresti volerlo, però? Sono sicuro che ci sono progetti di animali domestici per farlo "solo perché", ma non sono utilizzati seriamente.


5

Tu hai detto:

Java è spesso elogiato per la sua straordinaria portabilità, che presumo sia dovuta alla JVM.

E lì, nella prima frase, ti sbagli. Java non è portatile a causa della JVM. Java è portatile, perché il linguaggio Java è definito in modo tale da non lasciare alcun margine di manovra all'attuatore nel modo in cui un programma può comportarsi.

Ad esempio, Java ha due tipi "int" (intero a 32 bit con segno) e "lungo" (intero a 64 bit con segno). C e C ++ hanno "int" (firmato almeno 16 bit), "long" (firmato almeno 32 bit) e "long long" (firmato almeno 64 bit). Questo perché C dovrebbe funzionare su molti processori diversi e consente loro di comportarsi diversamente.

C avrebbe potuto definire dimensioni fisse per questi tipi. In tal caso, i processori a 36 bit non avrebbero potuto implementare il linguaggio C. E non possono davvero implementare Java! Quindi C ha permesso alla lingua di funzionare con una varietà di computer diversi. È inevitabile che ciò consenta la creazione di codice non portatile. È una questione di lingua.


È possibile emulare l'aritmetica a 32 bit su una macchina a 36 bit AND Andando il risultato di ogni operazione con 0xFFFFFFFF per troncarla a 32 bit. Quindi, queste macchine potrebbero implementare Java, sarebbe solo più lento che se Java consentisse tipi non basati su.
dan04

4

Java è altamente portatile in particolare perché il linguaggio è indirizzato alla Java Virtual Machine, che, come suggerisce il nome, non è una macchina reale . Poiché è possibile implementare una macchina virtuale sull'architettura di molti diversi tipi di macchine reali, un programma basato su JVM è altamente portatile.

C, d'altra parte, è specificamente progettato per essere eseguito su hardware reale, perché è stato creato per lo scopo specifico di implementare un sistema operativo, che necessita dell'accesso completo all'hardware. Ciò significa che il codice C non è particolarmente portatile in base alla progettazione e quando si esegue il porting di un programma C da una piattaforma all'altra, è necessario riscrivere in un modo o nell'altro varie parti specifiche dell'architettura di destinazione.


7
C è altamente portatile. Devi solo ricompilare sulla piattaforma di destinazione ed evitare quei pochi bit che sono specificamente e intenzionalmente non portatili.
Robert Harvey,

5
@RobertHarvey: ... cose fondamentali come le dimensioni di vari primitivi? ;)
Mason Wheeler,

2
Sì, quelle cose. È un peccato che il problema esista, ma il linguaggio è completamente trasportabile in tutti gli altri modi e ci sono modi per assicurarsi che le dimensioni primitive funzionino su tutte le piattaforme.
Robert Harvey,

3
@RobertHarvey: Direi che C rende possibile scrivere programmi portatili, ma non lo rende intrinsecamente facile.
Doc Brown,

2
@RobertHarvey: vuoi iniziare una guerra religiosa? ;-) La mia lingua portatile preferita è Python.
Doc Brown,

3

Esistono in realtà versioni interpretate di C , ma sono principalmente pensate per essere utilizzate per una sperimentazione rapida piuttosto che per un sistema di produzione.

Non sono all'ordine del giorno, perché dopo tutto, perché dovresti subire tutte le idiosincrasie in C se non per ottenere un eseguibile piccolo, veloce e statico?


3

Teoricamente sia C che Java possono essere entrambi compilati in codice nativo, interpretati o compilati in una macchina virtuale.

Il motivo tecnico per cui C non viene compilato in una macchina virtuale è semplicemente che non esiste una macchina C virtuale standard .

E nessuno sembra voler definire una macchina virtuale C, o persino compilare la macchina virtuale Java (che è perfettamente possibile). Probabilmente perché nessuno che usa C vuole perdere la sua velocità senza pari. Probabilmente anche perché C è il più forte nella comunità open source che può facilmente fare portabilità mediante compilazione (distribuire e ricompilare il sorgente ed eseguire), quindi non sentono tale necessità di portabilità dell'esecuzione (distribuire ed eseguire un file binario) come chiuso lo sviluppatore della fonte lo fa.


1

In realtà, questo è fatto. Ci sono importanti compilatori che supportano la compilazione su LLVM (lo so clang, e credo che anche gcc lo faccia). Che LLVM può essere JIT proprio come il codice Java è compilato in bytecode che è JIT'd.

Tuttavia, ciò che rende Java "multipiattaforma" rispetto a C è che Java ha una grande libreria di runtime che è stata trasferita su molte piattaforme. C non segue esplicitamente questo paradigma.


C con POSIX può essere abbastanza portatile (con qualsiasi sistema POSIX), se si codifica con cura.
Basile Starynkevitch,

0

Ci sono alcune differenze importanti tra Java e C. Java è isolato dal sistema operativo tramite la java virtual machine (JVM). La JVM estrae il sistema operativo dal programma. Un'applicazione java potrebbe richiedere alla JVM un pezzo di memoria e la JVM chiede quindi al sistema operativo quella memoria. Esistono molte JVM per piattaforme / sistemi operativi diversi. JVM è ciò che consente l'esecuzione dello stesso programma java su piattaforme diverse.

Con C, non c'è isolamento del sistema operativo. I programmi C (di solito) vengono eseguiti direttamente sul sistema operativo, effettuando chiamate dirette al sistema operativo. Questo rende il programma C vincolato a un sistema operativo / piattaforma specifici. Qualsiasi programma non banale effettuerà chiamate nel sistema operativo. Inoltre, i programmi C vengono compilati nel codice macchina, che è specifico dell'hardware. Un programma C compilato per x86 non può essere eseguito direttamente su un processore ARM.


1
Java è compilato in bytecode indipendente dalla piattaforma che può essere (teoricamente, almeno) eseguito da qualsiasi JVM su qualsiasi piattaforma. C viene compilato in linguaggio assembly per qualsiasi CPU di destinazione (quindi se si sta prendendo di mira l'architettura x86, il compilatore C creerà un assemblatore x86 o un assemblatore amd64 se si sta prendendo di mira quell'architettura, o assemblatore ARM, ecc.). Quindi il linguaggio assembly viene trasformato in file oggetto (assemblatore binario, in realtà), che sono collegati in un file eseguibile (diversi formati, a seconda della macchina di destinazione).
Craig,

1
Nella specifica del linguaggio Java non c'è nulla che dica qualcosa sulla JVM e, di fatto, ci sono implementazioni di Java senza la JVM. Su Android, i programmi Java vengono eseguiti sulla VM Dalvik (ora obsoleta) o Android Runtime, esistono implementazioni di Java per l'interfaccia della riga di comando, implementazioni che vengono compilate in ECMAScript e implementazioni che vengono compilate in codice nativo. Esistono compilatori C che vengono compilati in JVM. Esistono compilatori C che vengono compilati in ECMAScript. Ci sono interpreti C.
Jörg W Mittag,
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.