E4_PALP
E4_PALP
E4_PALP
LINGUAGENS DE
PROGRAMAÇÃO
MSC Rafael De Moura Moreira
e-Book 4
Sumário
INTRODUÇÃO������������������������������������������������� 3
COMPILAÇÃO ����������������������������������������������� 4
INTERPRETAÇÃO����������������������������������������� 22
CONSIDERAÇÕES FINAIS���������������������������� 34
3
COMPILAÇÃO
O primeiro processo que estudaremos é a com-
pilação. Neste processo, o programa é traduzido
uma única vez para a linguagem nativa da máqui-
na, e ao final um programa executável é gerado.
Utilizaremos a linguagem C como exemplo para
ilustrar esse processo.
Introdução
Em outra oportunidade, estudamos que computa-
dores possuem uma linguagem nativa, conhecida
por linguagem de máquina. Essa linguagem é
representada por números binários – sequências
de dígitos 0 e 1 – representando diferentes instru-
ções que devem ser executados por seus circuitos
internos. Esses dígitos representam a passagem
ou ausência de sinal elétrico, já que os circuitos
digitais são formados por dispositivos que realizam
o chaveamento de eletricidade.
4
Quando utilizamos uma linguagem de nível mais
alto, mais próxima da forma humana de raciocinar
e de se expressar, os códigos precisam ser tradu-
zidos para essa linguagem de máquina. Quando
esse processo ocorre uma única vez, gerando ao
seu final um programa em linguagem de máquina,
ele é chamado de compilação.
Pré-processamento
O pré-processamento é uma etapa de preparação
antes do acionamento do compilador em si. Ele
“prepara” o código – que, a princípio, provavelmente
foi escrito de maneira a ser legível por outros seres
humanos – para ser mais facilmente compreendido
pelo compilador.
5
De fato, todas as linhas iniciadas pelo caractere “#”
em C são diretivas de compilação. Isso significa
que elas não são instruções do programa, e sim
instruções para o pré-processador que irão afetar
a compilação do programa.
6
não virarão funções em linguagem de máquina.
Ao invés disso, todos os trechos onde elas foram
chamadas também serão substituídas durante o
pré-processamento pelo código definido.
Compilação
A etapa de compilação é, possivelmente, a etapa
mais complexa. Enquanto em assembly cada linha
de código corresponde diretamente a uma instru-
ção de máquina, o mesmo não pode ser dito sobre
linguagens de alto nível. Uma linha de código em
linguagem de alto nível geralmente corresponde
a várias instruções de máquina.
7
sendo utilizados, mas também variáveis criadas
pelo programador, funções etc. Também é comum
que uma linha de código afete o trabalho de uma
linha anterior a ela, o que faz com que normalmente
um compilador analise o código mais de uma vez,
já que na segunda ele já sabe o que vem a frente.
8
uma técnica conhecida como inlining. Malhas de
repetição podem ter algumas de suas instruções
multiplicadas, e o número total de repetições da
malha em si reduzido, uma técnica conhecida
como loop unrolling, que também tem por objeti-
vo economizar recursos gastos na verificação da
condição de parada da malha.
Linking
Para que o código objeto esteja pronto para ser
utilizado e se torne útil, ele será ligado ou unido
a outros códigos objeto (como bibliotecas) para
finalmente se tornar um programa executável ou
outra biblioteca.
9
O termo “biblioteca” é um termo um pouco “guar-
da-chuva” que utilizamos em alguns contextos
diferentes. Um deles é quando temos códigos
escritos na mesma linguagem (ou em linguagens
compatíveis) que podem ser importados para
utilizarmos na escrita de nosso código.
10
gerar pelo linker, resultando em outra biblioteca
ou em um programa executável.
Figura 1: O funcionamento do linker.
Fonte: QEF. Input and output file types of the linking process.
2009. Disponível em https://en.wikipedia.org/wiki/Interpreter_
(computing)#/media/File:Linker.svg. Acesso em: 24 set. 2021.
O programa em execução
Em várias plataformas modernas, o programa em
execução terá alguns elementos em comum. Sua
memória total conterá uma área de código e uma
área de dados, e esta será subdividida em duas
regiões: o stack (pilha) e o heap (monte).
11
dados frequentemente e para isso possui uma área
designada para armazená-los.
12
não é esvaziado sozinho. Memória alocada no heap
em linguagens como C fica sob responsabilidade
do programador. Se o programa não informar ao
sistema que acabou de a usar, ela ficará marcada
como ocupada, gerando um problema conhecido
como vazamento de memória.
13
abrir um parêntese e não lembrar de fechá-lo). Esse
tipo de erro é capturado pelo próprio compilador,
pois, ao passar pelo programa, ele irá notar um
comando não reconhecido ou a falta de algum
símbolo que era esperado. O processo de compi-
lação será interrompido e uma mensagem de erro
será exibida.
14
travar ou ser fechado pelo sistema operacional.
Em algumas linguagens, existe também o conceito
de exceções em tempo de compilação, permitindo
que um possível erro de compilação leve a uma
ação alternativa ao invés da falha na compilação.
Polimorfismo
Na programação orientada a objeto há o conceito
de polimorfismo: um objeto de uma certa classe
pode ser tratado como pertencente a outra classe
ou a algum outro tipo de categoria desde que sejam
respeitadas certas condições.
15
o que chamamos de assinatura de um método:
seu nome, seu tipo de retorno e seus parâmetros.
Quando uma classe implementa uma interface, ela
assume o compromisso de possuir métodos que
respeitem as assinaturas previstas. Portanto, um
trecho de código feito para trabalhar com aquela
interface aceitará objetos de qualquer classe que
implemente aquela interface, também sem fazer
distinção entre as classes.
16
objeto diferente será passado para aquela função,
e, dependendo da classe, um método login diferente
será executado. Chamamos esse tipo de caso de
polimorfismo em tempo de execução, pois nem
sequer o compilador sabia previamente qual ou
quais métodos seriam chamados por aquela função.
17
contínuas na memória, geralmente armazenando
diversos valores de um mesmo tipo. Eles podem
ser acessados através de um índice, um número
indicando qual das “casinhas” dentro da faixa
contínua gostaríamos de acessar.
18
compilador irá pegar o erro em potencial, evitando
que o programa seja gerado com essa falha.
Compilação cruzada
Um programa escrito em uma certa plataforma
não precisa, necessariamente, ser projetado para
executar na plataforma onde ele foi escrito. Vamos
considerar um exemplo bastante claro: um aplica-
tivo para smartphone, que será executado em um
aparelho com sistema iOS ou Android.
19
Desenvolvedores costumam programar utilizando
PCs convencionais, como laptops ou desktops e
sistemas operacionais como Windows, MacOS ou
Linux – mesmo quando eles pretendem desenvol-
ver aplicativos para smartphones ou para qualquer
tipo de computador embarcado.
20
-alvo. Através de um cabo ou de alguma forma de
comunicação sem fio, o computador utilizado no
desenvolvimento se comunica com o dispositivo
sendo testado e solicita uma série de informações
para monitorar o que está ocorrendo durante a
execução do programa.
21
INTERPRETAÇÃO
Quando um filme estrangeiro chega ao Brasil, é
comum que seja oferecida a opção de assisti-lo
dublado: uma equipe recebeu o filme na língua
original bastante tempo antes da data de lançamen-
to, traduziu todas as suas falas para o português
e uma equipe de atores especializados gravou
essa tradução. Ao final desse processo, o filme
está permanentemente disponível em português.
O processo de compilação de um programa, que
estudamos no capítulo anterior, é análogo a essa
tradução.
22
um programa chamado de interpretador daquela
linguagem. O interpretador irá abrir nosso código,
ler cada linha e imediatamente realizar a instrução
descrita naquela linha.
23
te associada ao compilador ou interpretador em
questão.
24
PROCESSOS HÍBRIDOS
Para atenuar os problemas de desempenho tipi-
camente associados às linguagens interpretadas,
diversas implementações começaram a adotar
alguns processos relacionados à compilação,
enquanto se tenta preservar a linguagem ao me-
nos parcialmente interpretada para não perder as
vantagens, como a portabilidade do programa (o
mesmo programa poder rodar em vários sistemas
sem a necessidade de gerar executáveis diferentes).
25
dependente da arquitetura para a qual ele foi com-
pilado, e não é compatível com outros sistemas
computacionais, enquanto um programa escrito
em linguagem interpretada pode ser executado
sem modificações em qualquer computador que
possua o interpretador adequado.
26
tornando a sua interpretação muito mais eficiente
do que a interpretação direta de um programa em
linguagem de alto nível.
27
arquivos .py diferentes (a extensão padrão para
códigos Python), perceberá que apareceram diver-
sos arquivos .pyc, que é a extensão para códigos
Python compilados para bytecode. É possível
também instruir explicitamente o Python a gerar
e armazenar o bytecode, de modo que o código
seja enviado já pré-compilado para os usuários.
Compilação just-in-time
Outra etapa que você deve se recordar que ocorre
na compilação é a otimização específica para o
hardware-alvo. Essa etapa, ao contrário das outras
técnicas que mencionamos, não depende apenas
de lógica, mas da presença de recursos específicos
no hardware onde o código será executado.
28
cutando a máquina virtual, e por isso não pode se
beneficiar de seus recursos.
29
Um exemplo clássico é o Java. Para que seu com-
putador execute programas escritos em Java, você
deve ter alguma implementação da Java Virtual
Machine (JVM) instalada em seu computador –
independentemente de qual seja sua CPU ou seu
sistema operacional. O código Java é compilado
para o bytecode da JVM, e em sua primeira exe-
cução o JIT irá compilar partes do código para
binário nativo, resultando em um grande ganho
de performance.
SAIBA MAIS
Aplicações Android em geral são executadas por uma
máquina virtual conhecida como ART desde a versão
5.0, que substituiu uma máquina anterior conhecida
como Dalvik.
30
pela loja é um bytecode que será processado pelo ART,
podendo inclusive ser compilado para linguagem nativa
da CPU do celular.
31
JVM. Sendo assim, é perfeitamente possível um
programa em Kotlin utilizar uma biblioteca escrita
em Java e vice-versa, afinal, uma vez compilados,
todos eles são apenas programas em bytecode.
De maneira experimental, existe até mesmo Py-
thon compilando para JVM, uma implementação
conhecida como Jython.
32
FIQUE ATENTO
33
CONSIDERAÇÕES FINAIS
Nesta unidade, focamos nas diferentes formas
como um programa escrito em uma linguagem de
programação de alto nível – isto é, uma linguagem
mais conveniente para nós, seres humanos – pode
ser traduzido para instruções em linguagem de
máquina, a linguagem nativa do computador.
34
processos ocorrem durante a compilação e quais
ocorrem durante a execução, como a verificação
de certos tipos de erro ou a identificação de quais
funções serão executadas em uma certa região
do código.
35
linguagens levam a ideia a um patamar adicional,
acrescentando um compilador just-in-time ao
interpretador que decide durante a execução se
certas partes do bytecode devem ser compiladas
para a máquina nativa para ganhar desempenho
ou se serão apenas interpretadas mesmo.
36
Referências Bibliográficas
& Consultadas
BENNETT, J. An introduction to Python bytecode.
Opensource.com, 2018. Disponível em: https://
opensource.com/article/18/4/introduction-python-
bytecode. Acesso em: 24 de setembro de 2021.