O que impede C de ser compilado / interpretado / JIT?


9

O Java é frequentemente elogiado por sua incrível portabilidade, que eu presumo ser por causa da JVM. Minha pergunta é o que impede que C seja compilado / interpretado / JIT. Se sim, C também pode ser gravado uma vez e funcionar com qualquer dispositivo que você tenha. mas este não é um mecanismo popular para processar um programa em C.

Quais são as desvantagens do processamento C dessa maneira, também quais são as vantagens de processar Java dessa maneira e de não compilar com o código da máquina, além da portabilidade, é claro?


Sua pergunta já tem algumas respostas muito boas aqui: stackoverflow.com/questions/3925947/...
Doc Brown

2
@delnan Meu argumento é que "o que impede C de ser compilado / interpretado / JIT'ed" realmente perde seu significado quando o idioma pode ter como alvo uma máquina virtual que tenha JIT ou situações em que a VM identifique os recursos ausentes no hardware e recompile o código para corresponder ao hardware existente (como o OpenGL (escrito em C) no OSX para diferentes placas gráficas). Não, você não pode pegar algo compilado para direcionar o llvm em uma máquina e executá-lo como tal em outro processador. Mas a linha compilada / interpretada / JIT pode ficar bastante desfocada.

11
O Java é frequentemente elogiado por sua incrível portabilidade. É portátil para sistemas em que a JVM foi compilada, ou seja, sistemas para os quais a JVM (escrita em C) foi compilada. Não há nada que impeça o tratamento do código C da mesma maneira, exceto que ninguém vê benefício suficiente em fazê-lo para justificar o esforço.
Pete Becker

2
Estou intrigado com esse trecho: "o que impede C de ser compilado / [...]". Nada?
Andres F.

11
Os compiladores C são bem rápidos atualmente, portanto, "make myprog.c; myprog" provavelmente será executado mais rapidamente do que a maioria dos intérpretes.
James Anderson

Respostas:


18

C é o que eu chamaria de linguagem de nível intermediário. Seu objetivo é servir como um "montador de nível muito alto", e é por isso que funciona tão bem como um destino de compilador, e por que ele também aceita a portabilidade.

Historicamente, os intérpretes costumam ser usados ​​com linguagens de alto nível, no contexto de chamadas de método. Na sua forma mais simples, um intérprete apenas analisa cada palavra-chave no idioma de origem, juntamente com seus tokens associados, e converte-o em chamadas e parâmetros de método. Na prática, o que a maioria dos intérpretes faz é converter o idioma de origem em alguma representação intermediária, e é essa representação que é interpretada.

O que impede C de ser interpretado ou Jitted? Nada. Mas essa não é a razão de ser de C.


6

Antes de tudo, vale a pena notar que a JVM da Sun foi escrita em C. C é uma linguagem muito popular quando é necessária portabilidade.

A linguagem C é portátil, embora muitos programas em C não sejam. Isso ocorre porque C não impõe tantas restrições ao programador nem faz tantas suposições. Se um programador de C quer que seus programas sejam portáteis, ele deve impor essas restrições.

Na prática, isso realmente não é muito mais difícil do que viver com as restrições que o Java força sobre você. É principalmente uma questão de estar atento aos seus tamanhos iniciais e primitivos, e usar bibliotecas portáteis como GTK + em vez de bibliotecas específicas da plataforma.

Você poderia criar um destino GTK + e um compilador C que suportasse uma máquina virtual, mesmo provavelmente a JVM, e fazer com que o código existente funcionasse com muito poucas alterações. De fato, sem a coleta de lixo, uma máquina virtual C provavelmente seria muito mais simples. Por que você iria querer?

O contrário, compilar Java para código nativo, é igualmente factível. Isso é basicamente o que o JIT faz. Por que você iria querer? Tenho certeza de que existem projetos de estimação para fazê-lo "apenas porque", mas eles não são muito usados.


5

Você disse:

O Java é frequentemente elogiado por sua incrível portabilidade, que eu presumo ser por causa da JVM.

E aí, dentro da primeira frase, você está errado. Java não é portátil por causa da JVM. Java é portátil, porque a linguagem Java é definida de uma maneira que não deixa ao implementador nenhuma margem de manobra no comportamento de um programa.

Como exemplo, Java possui dois tipos "int" (inteiro assinado de 32 bits) e "longo" (inteiro assinado de 64 bits). C e C ++ têm "int" (assinado pelo menos 16 bits), "longo" (assinado pelo menos 32 bits) e "longo longo" (assinado pelo menos 64 bits). Isso ocorre porque C é executado em muitos processadores diferentes e permite que eles se comportem de maneira diferente.

C poderia ter definido tamanhos fixos para esses tipos. Se tivesse, processadores de 36 bits não poderiam ter implementado a linguagem C. E eles não podem realmente implementar Java! Então, C permitiu que o idioma funcionasse com uma variedade de computadores diferentes. É inevitável que isso permita a criação de código que não é portátil. É uma questão de linguagem.


É possível emular a aritmética de 32 bits em uma máquina de 36 bits e obter o resultado de cada operação com 0xFFFFFFFF para truncá-lo para 32 bits. Portanto, essas máquinas poderiam implementar o Java, seria mais lento do que se o Java permitisse tipos não baseados em et.
dan04

4

Java é altamente portátil, especificamente porque a linguagem é direcionada à Java Virtual Machine, que, como o nome indica, não é uma máquina real . Como você pode implementar uma Máquina Virtual na arquitetura de muitos tipos diferentes de máquinas reais, um programa baseado em JVM é altamente portátil.

C, por outro lado, foi projetado especificamente para ser executado em hardware real, porque foi criado com a finalidade específica de implementar um sistema operacional, que precisa de acesso total ao hardware. Isso significa que o código C não é particularmente portátil por design e, ao transportar um programa C de uma plataforma para outra, várias partes específicas da arquitetura de destino precisarão ser reescritas em um grau ou outro.


7
C é altamente portátil. Você só precisa recompilar na plataforma de destino e evitar os poucos bits que são específica e intencionalmente não portáveis.
Robert Harvey

5
@RobertHarvey: ... coisas tão fundamentais quanto o tamanho de várias primitivas? ;)
Mason Wheeler

2
Sim, essas coisas. É lamentável que o problema exista, mas o idioma é totalmente portátil de qualquer outra maneira, e há maneiras de garantir que tamanhos primitivos funcionem em todas as plataformas.
Robert Harvey

3
@RobertHarvey: Eu diria que o C torna possível escrever programas portáteis, mas não o torna inerentemente fácil.
Doc Brown

2
@RobertHarvey: você quer começar uma guerra religiosa? ;-) Minha linguagem portátil favorita é Python.
Doc Brown

3

Na verdade, existem versões interpretadas do C , mas elas devem ser usadas principalmente para experimentação rápida, e não para o sistema de produção.

Eles não são comuns, porque, afinal, por que você sofreria todas as idiossincrasias C se não obtivesse um executável pequeno, rápido e estático?


3

Teoricamente, C e Java podem ser compilados em código nativo, interpretados ou compilados em uma máquina virtual.

O motivo técnico pelo qual C não é compilado em uma máquina virtual é que simplesmente não existe uma máquina virtual C padrão .

E ninguém parece querer definir uma máquina C virtual, ou mesmo compilar com a máquina virtual Java (o que é perfeitamente possível). Provavelmente porque ninguém que usa C quer perder sua velocidade incomparável. Provavelmente também porque C é mais forte na comunidade de código aberto que pode facilmente portar por compilação (distribuir e recompilar o código-fonte e executar), para que eles não sintam essa necessidade de portabilidade de execução (distribuir e executar um binário) como fechado desenvolvedor de origem fazer.


1

Na verdade, isso é feito. Existem grandes compiladores que suportam a compilação para o LLVM (eu sei que o clang suporta e acredito que o gcc também). Esse LLVM pode ser JIT'd, assim como o código Java é compilado no bytecode, que é JIT'd.

No entanto, o que torna o Java "multiplataforma" em comparação com o C é que o Java possui uma grande biblioteca de tempo de execução que foi portada para muitas plataformas. C explicitamente não segue esse paradigma.


C com POSIX pode ser bastante portátil (para qualquer sistema POSIX), se você codificar com cuidado.
Basile Starynkevitch

0

Existem algumas diferenças importantes entre Java e C. O Java é isolado do sistema operacional por meio da Java Virtual Machine (JVM). A JVM abstrai o sistema operacional do programa. Um aplicativo java pode solicitar à JVM um pedaço de memória e, em seguida, a JVM solicita ao SO essa memória. Existem muitas JVMs para diferentes plataformas / sistemas operacionais. A JVM é o que permite que o mesmo programa java seja executado em plataformas diferentes.

Com C, não há isolamento do SO. Os programas C (geralmente) são executados diretamente em cima do sistema operacional, fazendo chamadas diretas. Isso vincula esse programa C a um sistema operacional / plataforma específico. Qualquer programa não trivial fará chamadas para o sistema operacional. Além disso, os programas C são compilados no código da máquina, que é específico do hardware. Um programa C compilado para x86 não pode ser executado diretamente em um processador ARM.


11
Java é compilado em um bytecode independente de plataforma que pode ser (teoricamente, pelo menos) executado por qualquer JVM em qualquer plataforma. O C é compilado na linguagem assembly para qualquer CPU que você está alvejando (por isso, se você estiver alvejando a arquitetura x86, o compilador C criará o assembler x86 ou o amd64 assembler, se você estiver alvejando essa arquitetura ou o ARM assembler, etc.). Em seguida, a linguagem assembly é transformada em arquivos de objeto (montador binário, na verdade), que são vinculados a um arquivo executável (vários formatos diferentes, dependendo da máquina de destino).
Craig

11
Não há nada na Java Language Specification que diga algo sobre a JVM e, de fato, há implementações de Java sem a JVM. No Android, os programas Java são executados na Dalvik VM (agora obsoleta) ou no Android Runtime, existem implementações de Java para a CLI, implementações que compilam no ECMAScript e implementações que compilam no código nativo. Existem compiladores C que são compilados na JVM. Existem compiladores C que são compilados no ECMAScript. Existem intérpretes em C.
Jörg W Mittag
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.