My life in English

Aiming to be a Canadian citizen.

Vamos aprender a programar em C/C++? Lição 05: compilação, linkedição e chamadas a bibliotecas

Posted by fabianovasconcelos on 12 de September de 2009

Salve, galerinha do país com a maior densidade de canalhas do mundo!

Aos que acreditam piamente que José Sarney é inocente, notem que alguns termos são um link para páginas externas. Clique neles, se necessitar de alguma informação complementar a respeito.

Tá mais perdido que eleitor do Governador do Distrito Federal? Pois você veio parar num curso on line de C/C++! Clica aqui pra ver o índice!

A bola da vez agora são os aspectos de compilação. Tanto atendendo a pedidos, quanto porque já estava no cronograma. De agora em diante, nós vamos entender, cada vez mais, como funciona aquele programinha do “HELLO WORLD!” que a gente escreveu no post passado.

Recaptulando o que foi estudado anteriormente, eu vou citar um parágrafo do post anteior:

Na linha 2 você vê o texto #include <stdio.h>. A diretiva #include fala pro compilador (na realidade o pré-processador) incluir no seu código, MAIS CÓDIGO! pois é. É que se você tivesse mesmo que programar, digitar, escrever tudo que é necessário pro seu programa funcionar, você iria apanhar mais que cão pra ir pra missa. Só pra você ter uma idéia, #include <stdio.h> é traduzido como: “além do que eu escrever aqui, eu quero que se junte ao meu código um outro pedaço de código do arquivo stdio.h, que está num diretório, do meu compilador,  lá na casa do caramba”. O arquivo em questão são instruções de entrada e saída padrões para o programa. Ainda bem que alguém já escreveu isso por nós.

Baseado nisso daí, a gente vai começar a entender o processo de linkedição.

Imagine que você já é um programador profissional. Um cara que faz grandes programas, ou seja, um garoto de programa. Se for menina, uma garota de programa. (Garotas de programa, comentem aqui! Vocês estão em falta).

Então você é contratado pra fazer um programa bem grande, um programa que levará mais de um mês pra ficar pronto, trabalhando todos os dias, 8 horas por dia. Você começa o seu código devagarinho, com a função main, que é a primeira função de um programa em C. Inicialmente o programa tem só 10 linhas. De repente, no final do dia, ele já tem 800 linhas. No final da semana ele já tem 6000 linhas. Aí você fica espantadérrimo com aquilo tudo. “Nossa! Fui eu sozinho quem fez isso?”  Foi, sim! É porque leu o blog do NewWave, oras!

Acontece que, toda vez que você escrevia uma função nova, tinha que compilar o programa inteiro pra testar aquela função, saber se ela estava bem escrita, sem bugs (erros), se precisava ajustar algo, acrescentar algo, etc. Mas o processo de compilação de um programa é tão demorado quanto o seu tamanho, ou seja, quanto mais o programa cresce em linhas de código, mais demorado é pra transformá-lo em binário. Tem programas que demoram horas pra compilar. Pensando nisso, a galera do C resolveu permitir a divisão dos programas em arquivos, onde você pode muito bem criar seus códigos em módulos. Assim, quando você terminar de criar um módulo (em forma de um arquivo relativamente pequeno) é só compilá-lo e juntar ao restante do código que já foi compilado anteriormente. Isso se chama LINKEDIÇÃO! Agora vamos detalhar tudo isso pra uma melhor compreensão.

Ah! Como é boa e pacata a vida de programador!

Ah! Como é boa e pacata a vida de programador!

  • Bibliotecas

Provavelmente você já deve ter ouvido falar, no mundo da informática, das “bibliotecas”. Não, não se trata de um lugar grande, cheio de prateleiras e livros. Eu estou falando de subprogramas de computador, arquivos binários, geralmente não executáveis que ficam armazenados em diretórios específicos de sistema.
Como você já deve ter entendido, as bibliotecas podem ser anexadas ao programa em tempo de compilação ou em tempo de execução. Para isso existem dois tipos de biblioteca: a biblioteca dinâmica (dynamic library) e a biblioteca estática (static library). A diferença de uma pra outra é o momento de atuação. Não se apavore! Eu falei atuação e não autuação.

Falando de bibliotecas dinâmicas, quando um programa é compilado, ele fica igual a um queijo suiço, ou seja, cheio de buracos. No momento em que ele é executado e todas as vezes que ele é executado, as bibliotecas dinâmicas são chamadas pelo linker pra tapar esses “buracos” e o programa rodar certinho. Aí sim ele ficará completo. Bibliotecas dinamicas mas são, praticamente, programas como qualquer outro, a diferença é que não são chamadas diretamente pelo usuário, mas carregadas apenas por outros programas. Exemplos de bibliotecas dinâmicas: as dll’s do windows e os .so do linux.
Já no caso das bibliotecas estáticas, as coisas acontecem um pouco diferente. No processo de compilação, o linker une o programa que você escreveu (compilado) com as bibliotecas estáticas necessárias ao funcionamento do programa. Após esta operação, acontece a fusão, tornando-se tudo um só arquivo, programa e biblioteca(s). Essa fusão não acontece com a linkedição dinâmica e esse processo só acontece uma única vez. Exemplos de bibliotecas estáticas: as .a e as .lib.

Bibliotecas geralmente são de uso genérico, ou seja, uma mesma biblioteca pode ser o complemento de muitos programas. Por exemplo, a biblioteca vbrun.dll, do Micro$oft Rwindows, é requerida em muitos programas que tem como base o VB (visual basic) pra que estes consigam rodar. Isso livra o programa de ter um tamanho monstruoso. Pensa aí: se eu tenho cem programas, no mesmo HD, que necessitam de uma mesma biblioteca, e esta biblioteca é relativamente grande em bytes, pra que é que eu vou incorporar a mesma biblioteca cem vezes em cada programa, se eu posso ter apenas uma cópia compartilhada para todos os programas? Seria idéia de eleitor do Collor, não é mesmo? Mas aí já sabe: se a biblioteca requerida pelo programa não estiver presente no seu PC ou se estiver na pasta errada que não a pasta padrão das bibliotecas, o programa não vai rodar e vai emitir um erro.

Em alguns casos as bibliotecas são escritas em Assembly (linguagem dos deuses), porque existem coisas que C/C++ não consegue manipular nativamente. Os dispositivos e instruções de entrada e saída, por exemplo. Como lidar com o teclado, mouse, monitor, etc? Pra isso não tem jeito: é coisa de baixissímo nível e deve ser escrito em baixíssímo nível. ASM neles! Por isso se optou por usar o sistema de bibliotecas. Tem coisas que, mesmo o C/C++, poderosíssimos como são, não dão de conta. Agradeçam aos caras que implementaram a linguagem. Se não fosse por eles, você é quem teria essa dor de cabeça.

O nome do processo de linkar um programa com suas respectivas bibliotecas, sejam elas dinâmicas ou estáticas, chama-se linkedição.

  • Arquivos de cabeçalho

Voltemos ao programinha “Hello, World!”. Lembram daquela primeira linha? A #include <stdio.h>? Pois é. Aquela linha, como já foi dito antes, é a responsável pela inclusão (linkedição) do seu programa com as bibliotecas necessárias a execução do programa. Como já foi dito anteriormente, o linker é que é o responsável em linkar bibliotecas a programas e os arquivos de cabeçalho dão as instruções para que o linker faça tudo direitinho. Todas as vezes que você vir num código em C/C++ uma cerquilha # acompanhada de mais alguma coisa, pode ter certeza de que aquilo é uma diretiva do pré-processador. As diretivas do pré-processador servem pra colocar o pré-processador em ação. Umas das diretivas do pré-processador é a diretiva #include (não esquente a moringa, você vai ver o resto das diretivas depois, aos poucos). A diretiva #include diz ao pré-processador para incluir um determinado arquivo ao código. No caso do nosso programa, o arquivo a ser incluso é o <stdio.h> (o nome do arquivo deve ficar entre os sinais menor que e maior que). O arquivo stdio.h é um arquivo de cabeçalho, ou header, por isso .h. Não confunda: o pré-processador não é responsável por linkar bibliotecas e programas, quem faz isso é o linker. A unica coisa que o pré-processador faz é substituir macros e resolver os includes. Arquivos .h não são bibliotecas, são apenas arquivos de definições.

Ainda está obscuro? Calma que eu ainda não terminei. Isso é mais fácil do que entender a cabeça das meninas.

Vejamos o nome do arquivo em questão: stdio.h. std, vem de standard, ou padrão. io, vem de input e output, ou seja, entrada e saída. Não é preciso ser Stephen Hawking pra concluir que esse arquivo trata exatamente de como manipular a entrada e saída padrão nos programas feitos em C/C++, né? Pois é! Na real, os arquivos de cabeçalhos são intermediários. Eles não contém exatamente o código que se deseja usar. Eles contém informações de onde pode ser achado o código desejado. Ao invés de conter a função toda escrita, eles contém simplesmente os protótipos das funções e, falando a grosso-modo, aponta qual(ais) a(s) biblioteca(s) deve(m) ser usada(s) na ocasião.
Se, ainda assim, estiver obscuro, se acalme! No decorrer do curso nós veremos mais coisas relativas ao assunto deste capítulo.

  • Padrão ISO/ANSI

Vocês já ouviram falar em ISO? E ANSI?

Sim! ISO (International Organization for Standardization) é aquela daquela conversa de ISO9002, ISO9001, etc. que estamos acostumados a ver as empresas se gloriando de ter recebido. É um comitê internacional de padronização. Eles arrumam tudo que está bagunçado (nem pense, eles não arrumam o seu quarto e nem o seu casamento). Quer ver um exemplo do trabalho deles? O CD que você escuta (ou escutava, antes de aprender a baixar músicas via P2P) tem aquele formato redondo, naquela espessura, com aquele tamanho de raio, diâmetro do buraco no meio, com todas aquelas características por conta de uma padronização. Esta padronização é reconhecida pelo ISO e publicada em um documento.

Paralelamente, como sempre, os estadunidenses, com as suas manias de não quererem se misturar com o resto do mundo e quererem enfiar goela abaixo o seu estilo de vida, criaram o ANSI (American Nacional Standartd Institute), que é o orgão de padronização estadunidense. Como todo mundo sabe, eles não usam, pro exemplo, o metro como medida padrão, nem quilos, nem qualquer outra medida do Sistema Internacional. O basquete da NBA tem regras diferentes das regras oficiais olímpicas. A mesma empresa que vende o sistema operacional mais usado no mundo quer impor um HTML diferente, que só eles usam. Por que não também não inventar uma linguagem C e C++ diferentes, só pra dizer que “não se misturam”? Pois foi. Senhoras e senhores, existe também, além do C ISO e C++ ISO, o C ANSI e C++ ANSI. Mas não esquentem com isso. Programem em C/C++ ISO.

Da mesma forma acontece com as linguagens C e C++. A galera que as criou, deixou-as soltas, e aos poucos cada um vinha e metia o bedelho nelas, fazendo uma bagunça sem tamanho. Mas, rapidamente, notou-se que a coisa tava virando cabaré e resolveram padronizar a linguagem. Hoje, as palavras-chave, as bibliotecas padrão (aquelas oficiais, escritas pelos implementadores do C e C++), o estilo de programação, tudo está documentado e padronizado.

Apesar das bibliotecas padrão, tanto em C, quanto em C++, serem relativamente ricas em conteúdo, contendo, por exemplo, funções matemáticas* que você não precisará escrever, ou funções de manipulação de strings (calma, você saberá o que é isso no seu tempo certo, não se afobe), existem certos códigos que não foram implementados na biblioteca padrão, então, se você precisar de um código em particular, você tem duas opções: (1) crie a sua pŕopria biblioteca (o que não é nada difícil e até mesmo eu encorajo a você a criar); (2) adiquira de alguém ou alguma empresa a biblioteca pronta. O princípio do C e C++ é: reutilizar, reutilizar, reutilizar. Pra quê ficar feito pateta reescrevendo código que já existe? Se já existe e você tem como pegar, linke com o seu código e pronto! Cuidado: existem códigos proprietários que você só pode ter mediante pagamento. Não vão sair dizendo por aí que eu tô incentivando a pirataria.

Existem duas coisas que eu preciso dizer a respeito de criar as suas própias bibliotecas: (1) outras pessoas podem usar o código que você escreveu, e poupar o trabalho de monte de gente; (2) não tente reescrever os códigos da biblioteca padrão pensando que você vai fazer melhor que do que já está lá. Esses códigos foram testados e retestados um milhão de vezes,e dificilmente você fará melhor que os caras. Mesmo assim, se quiser tentar, fique a vontade. Se você conseguir algo de significativo, parabéns, você ganha uma bolsa de estudos no MIT bem rapidinho.

Existe uma parte significativa e notável da biblioteca oficial C++ que se chama STL (Standard Template Library) e foi criada por Alexander Stepanov e Meng Lee, na Hewlett-Packard.

  • DLL, LIB, .a e .so

Não é possível que um usuário do rwindows, que goste de tecnologia e tenha interesse em aprender, não tenha ouvido falar, mesmo que seja de longe, na sigla dll. Pois é. Dll significa Dynamic-link library (Biblioteca de ligação dinâmica). Esta é a principal implementação de biblioteca da Microsoft. A implementação padrão deles. Outro formato bastante usado por quem programa pra windows é o .lib. Apesar de existirem mais formatos, vamos ficar com esses dois na memória, pra não complicar.

No caso do Linux, os formatos mais conhecidos e usados são: .a e .so. Também vamos ficar só com esses dois. Pro nosso estudo, tá de bom tamanho. Querem saber mais sobre esses formatos? Google!

Well, eu espero que esse post tenha sido esclarecedor. Mais uma vez, me desculpem a demora em postar, mas é que apareceram aí uma ruma de pepinos que eu tive de desembargar. Na realidade, esse foi o post mais complicado que eu tive que escrever. Eu sou réu confesso que tive que estudar bastante pra escrevê-lo. E já sabem: se acharem erros ou algo que não concordam, postem! Não paga nada.

Por fim, cliquem AQUI, para ler um artigo filé mignon sobre pré-processadores, by UNICAMP. Eu recomendo deixar essa preguiça nojenta de lado e ler de verdade. Pra sair e beber cachaça ou transar não tem preguiça não, né? Se não entenderem agora, não se preocupe: não se trata de burrice e nem em linguagem difícil de aprender. É que eu ainda preciso explicar muita coisa que tem escrito lá. Mas a simples leitura, mesmo sem entender, já abre a mente, desperta a curiosidade e você se familiariza com a linguagem.

Um grande abraço aos cuecas e um selinho nas calcinhas. Fiquem com DEUS!

Fui!

*O arquivo de cabeçalho usado aqui é <math.h>.


NA CLÍNICA PARA DEFICIENTES

Na hora do almoço, um interno ia passando pelo refeitório, quando o cozinheiro lhe pergunta:
– Quer uma torta, amigo?
– Agora não, obrigado! Acabei de comer uma ceguinha!


Copyright 2009 (C) Fabiano Bezerra de Vasconcelos – Todos os direitos reservados.

Advertisements

8 Responses to “Vamos aprender a programar em C/C++? Lição 05: compilação, linkedição e chamadas a bibliotecas”

  1. afdfdsf adfadsfad said

    Adorei a explicação, só que a linguagem é muito violenta, mantem-nos acordados do princípio ao fim

    • fabianovasconcelos said

      Obrigado pelo elogio, afdfdkjcsdclhdsjkhkjbvkbvbd!
      Mas isso de “linguagem violenta” quer dizer o quê? Coisa boa ou ruim?
      E o seu nome e sobrenome, é procedente de qual país? Parece russo!

      Boa semana!

  2. Adorei parabéns, muito esclarecedor…

  3. Roni_santos said

    Adorei a explicação.muito interativa (aprendi muito).

    • fabianovasconcelos said

      Ainda bem que gostou! Isso me deu um trabalho do caralho pra fazer! Kkkkkk…
      Um dia eu ainda vou continuar esse trabalho pra que mais pessoas possam vir aqui me elogiar e continuar dizendo que eu sou o máximo!

      Obrigado e volte sempre! 😀

  4. Vinicius Souza said

    Muito bom, parabéns, gostei bastante, há poucos erros. Aguardo novos posts!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: