Portabilidade no idioma C

10

Como exatamente é determinada a portabilidade de um idioma como C? Aprendi que os compiladores são específicos do ISA. Se isso for verdade, como o C é portátil? Ou será que apenas o código fonte escrito em C é portátil, mas não os executáveis? Os executáveis ​​ISA específicos para exemplos de aplicativos para x86 são separados dos aplicativos da Apple (supondo que a Apple use o microprocessador Motorola / PowerPC)?

KawaiKx
fonte

Respostas:

26

é que apenas o código fonte escrito em C é portátil e não os executáveis?

Corrigir. Algumas pessoas chamam de escrever uma vez, compilar em todos os lugares.

http://en.wikipedia.org/wiki/Write_once,_compile_anywhere .

A outra alternativa é escrever uma vez, executar em qualquer lugar. Java é um bom exemplo disso.

http://en.wikipedia.org/wiki/Write_once,_run_anywhere

E mesmo que você possa obter portabilidade parcial de plataforma cruzada, nunca espere que seu código seja executado em qualquer lugar sem modificações.

adolfojp
fonte
O código-fonte C não é portátil para diferentes compiladores, ISAs ou sistemas operacionais sem bastante shennanigans extra-linguais. Coisas simples como o tamanho e o alinhamento dos tipos padrão não são padrão em C, portanto, portar software que troque dados com outras instâncias por si só pode ser bastante desafiador. Consulte GNU Autoconf / Automake para obter um exemplo (possivelmente ofuscado) dos aros que os programadores C irão saltar para obter portabilidade.
Tim Williscroft
3
@ TimWilliscroft: Os problemas de portabilidade geralmente são causados ​​por bibliotecas não padrão e práticas de programação incorretas; e não são causados ​​por C ou por suas bibliotecas padrão. Um exemplo simples seria usar uma extensão GCC não padrão ou falhar na serialização / desserialização correta de dados para E / S.
Brendan
6

Não é apenas específico do ISA. Por exemplo, você pergunta:

aplicativos para x86 são separados dos aplicativos para apple?

Sim, eles são, mesmo que a Apple use hardware x86. Os binários C são específicos da arquitetura e do sistema operacional.

vartec
fonte
11
@ Steven314: Seu comentário é uma tangente. Não tem nada a ver com o hardware ser padrão ou não, e tudo a ver com o fato de o OS X ter um formato binário diferente (Mach-O) do que, digamos, no Linux (normalmente ELF).
Mipadi
@ Steve: EFI vs BIOS importa apenas para inicialização e sistemas operacionais internos; a arquitetura de hardware, que é o conjunto de instruções da CPU, é a mesma, porque é a mesma CPU.
Vartec
Comentários excluídos, principalmente porque eu nunca deveria ter incluído a coisa do mac em primeiro lugar. Minha menção à ABI (Application Binary Interface) e às convenções de chamada ainda podem ser relevantes (um terceiro item a ser adicionado à "arquitetura e sistema operacional"). Eles não são relevantes para o hardware, exceto que as ABIs tendem a ser projetadas para arquiteturas específicas (por exemplo, registros disponíveis), mas são relevantes para a portabilidade binária. Esse não é um problema de formato de arquivo - o ELF é usado no Windows e Linux (por gcc), mas você provavelmente não pode levar um arquivo de objeto de um para o outro.
21311 Steve314
@vartec você disse que os binários C também são específicos do sistema operacional, é porque o próprio sistema operacional é específico do ISA, assim os binários C se tornam indiretamente específicos do sistema operacional?
KawaiKx
@Saurabh - todos os executáveis ​​nativos são específicos do SO, porque o SO especifica o formato do arquivo. Além disso, uma biblioteca padrão C deve implementar muitas funções chamando o sistema operacional; portanto, mesmo se o formato do arquivo fosse padronizado, o código em si não poderia ser executado em outro sistema operacional. Isso é padrão para idiomas que compilam com código nativo, em oposição a algum código de máquina virtual, como a JVM (Java Virtual Machine). É possível compilar C para uma máquina virtual, mas nunca fiz isso que eu saiba. O LLVM é o mais próximo, mas pretende ser um back-end do compilador - não um ambiente de compilação, uma vez que é executado em qualquer lugar.
21311 Steve314
5

é que apenas o código fonte escrito em C é portátil e não os executáveis?

Exatamente. Você precisa recompilar seu programa C em todas as plataformas. Os compiladores C geram código de máquina que é portátil apenas em uma extensão muito limitada entre máquinas da mesma arquitetura de processador / memória e sistema operacional. É por isso que você vê distribuições binárias diferentes de aplicativos multiplataforma (por exemplo, navegadores), como "Linux de 64 bits da Intel" ou "Mac OS X de 32 bits do PowerPC" (OK, o último é apenas uma ilustração, eu sei que a Apple mudou para a Intel há alguns anos :-).

Péter Török
fonte
3

A maior parte da pergunta foi respondida, mas eu gostaria de acrescentar que a durabilidade é outra coisa que você deve levar em consideração.

Por exemplo, o JAVA pode ser gravado uma vez e executado em qualquer plataforma em que a VM (hoje, é chamada de "Runtime Environment"). Mas outra vantagem é que você pode executar o código Java 1.1 a partir de 1995 em sua máquina de 2011. O que não é possível se o seu código foi compilado no i386 e você tenta executá-lo na sua arquitetura AMD64.

Você também obtém as melhorias da própria máquina virtual.

Então, eu diria que, em geral, indo das linguagens menos portáteis para as mais portáteis, você teria: Assembler, linguagem compilada de baixo nível como C, depois C ++, linguagens interpretadas ou as que são executadas em uma máquina virtual.

Não sou realmente um defensor de Java, pelo menos não para a linguagem nem a comunidade, por exemplo, mas é o caminho a percorrer se você estiver procurando por portabilidade e a menor perda de desempenho em comparação com C.

tiktak
fonte
3

Boas respostas sobre escrever uma vez compilam em qualquer lugar.

As pessoas gostam de pensar em C como uma linguagem portátil, devido à sua popularidade e à alta probabilidade de um compilador C estar disponível para futuras plataformas de destino. Outro fator é a biblioteca padrão que ajuda nas tarefas comuns de programação de maneira independente da plataforma.

Então, eu diria que a portabilidade de um idioma é determinada por:

  1. Nível de padronização.
  2. Disponibilidade de compiladores para diferentes plataformas / arquiteturas.
  3. Profundidade e amplitude de bibliotecas portáteis.

Realisticamente, embora quase qualquer aplicativo C complexo exija algum trabalho para ser transferido para uma nova plataforma devido a dependências de hardware ou sistema operacional. Esse processo é conhecido como portabilidade.

Guy Sirton
fonte
3

"Portabilidade" tem vários significados. Com relação a C, significa o seguinte:

  • Os compiladores foram implementados para o C em uma ampla variedade de plataformas de hardware e sistema operacional, o que foi um grande negócio no início dos anos 70;

  • Há um padrão universalmente aceito para o próprio idioma, em oposição a cada implementação do compilador que reconhece uma variante ligeiramente diferente do idioma (novamente, um grande problema quando C foi projetado pela primeira vez, pois havia várias variantes de idiomas como Pascal e BASIC que não eram universalmente reconhecidos);

  • Devido a esse padrão, o código em conformidade produzirá o mesmo comportamento quando compilado em plataformas diferentes.

O código fonte é portátil, mas um novo binário deve ser gerado para cada destino.

Observe, no entanto, que a fonte C raramente é "trivialmente" portátil; a maioria dos aplicativos exige que você vá além do definido pelo padrão de idioma, usando extensões exclusivas de uma plataforma específica; portanto, na prática, o código-fonte não é 100% portátil.

Observe, no entanto, que C deixa bastante para a implementação. Os tamanhos exatos de vários tipos de dados, o comportamento em excesso, etc., dependem da implementação; o padrão fornece os requisitos mínimos aos quais uma implementação deve estar em conformidade, mas a implementação é livre para ir além desses limites.

John Bode
fonte
0

Qualquer que seja o ISA, C não é específico do ISA. Suponho que você não esteja se referindo ao slot agora obsoleto para placas de extensão para PC.

Existem compiladores C compatíveis com os padrões para muitas plataformas e, desde que você use recursos de linguagem totalmente definidos no seu código-fonte, poderá compilá-lo em qualquer compilador C para qualquer plataforma.

No entanto, um problema é que o padrão C deixa muitos comportamentos de recursos como implementação definida ou como comportamento indefinido. Isso é feito para tornar a linguagem C geralmente mais útil para programação de baixo nível, evitando casos em que algum comportamento definido com precisão é uma correspondência ruim para o que o hardware suporta em alguma plataforma. No entanto, torna um pouco mais difícil escrever programas portáteis.

Além disso, diferentemente de algumas linguagens, o C não é fornecido com uma enorme biblioteca do tipo que Java ou C # fornece. Você pode obter bibliotecas muito portáteis para fazer praticamente qualquer coisa, mas precisa trabalhar para construí-las e fazê-las funcionar juntas.

C tem uma biblioteca padrão, é claro, mas seu escopo é relativamente limitado em comparação com Java, C #, Python, etc.

Steve314
fonte
4
ISA = conjunto de instruções arquitetura aka arquitetura de hardware
vartec