Вы находитесь на странице: 1из 34

Implementao da

programao modular

Baseado em Arndt von Staa

Especificao
Objetivo dessa aula
Mostrar como implementar em C os conceitos de interface
nica, preservando o controle de tipos dos elementos
declarados nas interfaces entre mdulos

2 / 34

Sumrio
Declarao e definio
Pilha de execuo, registro de ativao
Classes de memria
Ligao
Pr-processamento
Padro de programao C para a interface de mdulos

3 / 34

O que ocorre ao declarar um elemento?


Ao declarar um nome em uma linguagem tipada
estabelecido
que o nome existe
que corresponde a valores de um determinado tipo
isto permite gerar cdigo que interpreta corretamente os valores
acessados a partir deste nome

4 / 34

O que ocorre ao definir um elemento?


Ao definir um nome em uma linguagem tipada
alocado o espao de dados a ser ocupado pelo valor
a extenso do espao depende do tipo

o nome amarrado ao espao

Ao somente declarar um nome, no definido o espao de


dados amarrado a esse nome
Ao definir um nome pode-se inicializar o valor do espao de
dados, exemplos
int x = 10 ;
char Mensagem[ ] = "texto da mensagem" ;

5 / 34

Exemplos de declarao e definio


De maneira geral, ao redigir o cdigo de uma declarao
ocorre tanto a declarao como a definio
int F( int X )
{
int Y = 10 ;
...
}

declara e define X e Y, sendo que X e Y fazem parte do


registro de ativao de F (automtico)
gera o cdigo de inicializao de Y a ser executado
imediatamente ao entrar na funo F
declara, define e inicializa F, sendo que o valor de F o
cdigo e que faz parte do segmento executvel (esttico)

6 / 34

Pilha de execuo
Topo da
pilha de
execuo

Y
X
ret
ant

Funo F

Y
X
ret
ant

Funo F

Cada registro de ativao C


contm:
ant: endereo do topo da
pilha do registro de ativao
anterior
ret: endereo de retorno de
execuo para aps o local
em que foi chamada
espaos para os parmetros e
variveis locais

Funo G
ret
ant

espaos para temporrios

Todos endereos locais so


deslocamentos relativos ao
topo da pilha de execuo

7 / 34

Exemplos de declarao e definio


int X ; fora de uma funo
declara e define X como global externado pelo mdulo

static int Y ; fora de uma funo


declara e define Y como global encapsulado no mdulo

extern int Z ;
somente declara Z como global externo ao mdulo

int G( float X) ;
somente declara a funo do tipo: ( float ) : int

Observao: static para variveis locais indica que


existe somente uma instncia da varivel, mesmo se existirem
n chamadas recursivas na pilha de execuo e
o valor preservado de uma ativao para outra, mesmo se
nenhum registro de ativao estiver na pilha de execuo
8 / 34

Restries para definies


Em C e C++
um nico mdulo do programa deve declarar e definir o nome
compartilhado
os demais mdulos devem somente declarar

Isso vale para nomes aos quais se associam espaos


nomes de variveis
nomes de funes
mas no para nomes de tipos
tipos so somente declarados

Podem-se declarar nomes e no utiliz-los


Quando se define um nome local e no o utiliza o
compilador emite uma mensagem de advertncia

9 / 34

Classes de memria real


Executvel
onde se armazena o cdigo a ser executado e,
possivelmente, algumas constantes numricas

Esttica encapsulada
contm todos os espaos de dados globais encapsulados
(declarados static), e todas as constantes literais definidas no
interior de mdulos

Esttica visvel
contm todos os espaos de dados globais externados

Automtica
contm a pilha de execuo do programa

Dinmica
contm espaos de dados alocados pelo usurio (malloc, new)

10 / 34

Outra classe de memria


Persistente
onde se armazenam os dados que estaro disponveis de
uma instncia de execuo do programa para outra
arquivos contendo parmetros de execuo
tipicamente os arquivos .dat e .ini

bases de dados
segmentos de memria virtual

11 / 34

Ligao
A ligao combina m >= 1 mdulos objeto e mdulos
contidos em uma ou mais bibliotecas, produzindo o
programa carregvel (.EXE, .COM)
No mdulo objeto todos os endereos gerados so
deslocamentos (offsets) relativos a zero dentro da
respectiva classe de memria
O ligador (linker) justape (concatena) os espaos de cada
uma das classes de memria (segmentos: executvel e
esttica) definidos nos mdulos objeto, formando um nico
grande espao para cada classe de memria
O estes dois grandes segmentos constituem o programa
carregvel

12 / 34

Composio de um mdulo objeto

M1.OBJ
Dados
estticos
Cdigo
Tab Reloc

Tab Simb

Declarados e definidos, relativos a 0


Relocvel, relativo a 0
Tabela de relocao
- informa os locais contendo endereos
a serem relocados
Tabela de smbolos
- referncias a nomes externos
declarados e no definidos (importados)
- referncias a nomes externos
declarados e definidos (externados
pelo mdulo)
13 / 34

Smbolos definidos no mdulo objeto


Cada mdulo objeto contm uma tabela de smbolos
agregando os nomes globais externos, particionada em
smbolos somente declarados
smbolos declarados e definidos

Os smbolos somente declarados definem uma lista de todos


os locais no cdigo (ou nos dados) em que o smbolo
referenciado
Um nome externo somente declarado em um determinado
mdulo necessariamente dever estar declarado e definido
em exatamente um outro mdulo do programa sendo
composto
i.e. cada nome deve ser definido em um nico mdulo

14 / 34

Composio de um executvel
p.exe
cdigo
0

dados estticos
0

m1

10
30

m1
m2

int a
int b

m3

int c
300

m2

b
c
530

Passos
1. concatenar os mdulos objeto
cdigo e dados estticos

2. relocar os endereos do
mdulo de modo que estejam
em conformidade com a
origem na concatenao
3. resolver os nomes externos ao
mdulo definidos em outro
mdulo

m3

15 / 34

Relocao
O ligador ajusta os endereos dos elementos contidos em
cada segmento de modo que passem a ser deslocamentos
relativos origem dos correspondentes segmentos do
programa
A relocao ocorre com relao aos segmentos
cdigo
esttico local e externo

A tabela de relocao contida no mdulo objeto informa os


pontos no cdigo e nos dados globais do mdulo que
devero ser ajustados
no mdulo objeto os deslocamentos so relativos a zero
para relocar basta somar a origem do segmento do mdulo
definida no segmento composto s referncias internas ao
mdulo registradas na tabela de relocao
16 / 34

Resoluo de nomes externos, sem bibliotecas


O ligador cria uma tabela de smbolos que conter os nomes
externos. Cada smbolo informa
o endereo no segmento composto
a lista dos locais que referenciam o smbolo ainda no definidos

Ao encontrar um nome externo


adiciona-o tabela caso ainda no figure l
se for um nome externo declarado e definido
se a tabela de smbolos do ligador j define o nome, emitido um erro de
duplicao de definio
caso contrrio, percorre a lista dos locais que referenciam o smbolo e atribui
o endereo definido

se for um nome externo somente declarado


se a tabela de smbolos do ligador j define o nome, atribui esta definio
aos locais no mdulo que referenciam este smbolo
caso contrrio, o ligador acrescenta a lista do mdulo lista do ligador

Ao terminar o processamento
para cada smbolo no definido contido na tabela do ligador, emitido
um erro de smbolo no definido

17 / 34

Resoluo de nomes externos, com bibliotecas

Uma biblioteca esttica (.lib) formado por


uma lista de mdulos
uma tabela de smbolos contendo os smbolos externados pelos
mdulos e a referncia para o cdigo do respectivo mdulo na
lista de mdulos

Aps compor todos os mdulos objeto, para cada smbolo


ainda no definido
o ligador procura este smbolo, segundo a ordem de
fornecimento das bibliotecas
caso seja encontrado, o mdulo correspondente extrado da
biblioteca e acrescentado ao programa sendo montado
para isso segue o procedimento anterior

caso no seja encontrado, emitido um erro de smbolo no


definido

repete at todos os smbolos terem sido processados


18 / 34

Ligao dinmica
Bibliotecas dinmicas (.dll) so carregadas medida que
forem acessadas durante o processamento
ao encontrar um smbolo externo ainda no resolvido
utiliza a .dll, se j carregada, ou ento carrega ela
substitui a referncia ao smbolo para a referncia funo

cada biblioteca compartilhada por todos os programas que a


usem
cada programa estabelece espaos prprios para os dados

Vantagens
uma biblioteca dinmica carregada uma nica vez
considerando todos os programas em execuo simultnea
pode-se trocar uma biblioteca sem precisar recompilar ou
religar todo o programa

19 / 34

Ligao dinmica
Problemas
precisa-se projetar com muito cuidado as bibliotecas
dinmicas, visando explicitamente a possibilidade do seu reso
em diversos programas
as bibliotecas so conhecidas pelo nome, portanto pode ocorrer
coliso de nomes
bibliotecas diferentes com o mesmo nome

necessrio assegurar que a verso correta da biblioteca seja


utilizada com cada um dos programas
todos os programas utilizam a mesma verso da biblioteca, a
menos que se possa armazenar as bibliotecas em locais distintos
todos evoluem medida que as bibliotecas forem evoluindo

20 / 34

Carga de um programa
Para poderem ser executados programas precisam estar em
memria real
fragmentos de um programa executvel podem estar em
qualquer um dos segmentos: executvel, pilha (automtico),
esttico, e dinmico. A origem estar no segmento executvel.

Ao ativar um programa ativado o carregador que recebe


como parmetro o nome do arquivo contendo o programa a
ser carregado
O carregador
determina onde sero colocados os segmentos executvel e
esttico e copia os segmentos do arquivo para a memria
efetua as necessrias relocaes de modo a ajustar os
endereos contidos nesses segmentos
ativa o programa chamando a funo main( ) (ou winmain( ))
21 / 34

Pr-processamento
Um pr-processador
um processador de linguagem
recebe um arquivo contendo texto fonte e diretivas de prprocessamento
produz um outro arquivo de texto fonte na mesma linguagem

22 / 34

Pr-processamento em C / C++
#include <nome-arquivo>
procura o arquivo no domnio do compilador e o inclui

#include "nome-arquivo"
procura o arquivo no domnio do usurio e o inclui

#define NomeElem ValorElem


define o nome NomeElem
provoca a substituio de todas as ocorrncias de NomeElem no
cdigo por ValorElem
ValorElem pode ser o string nulo (vazio)

#undef NomeElem
retira o nome NomeElem da tabela do pr-processador

#pragma
permite informar coisas especficas ao compilador
23 / 34

Pr-processamento em C / C++
#if Expresso
TextoTrue compilado se expresso != 0
#else
TextoFalse compilado se expresso == 0
#endif
#ifdef Nome
ou ao contrrio #ifndef Nome
TextoTrue compilado se Nome estiver definido
#else
TextoFalse compilado se Nome no estiver definido
#endif
Operador de pr-processamento: defined( nome )
Outros: #nome converte nome para string

##nome copia nome (usualmente um parmetro de macro)


24 / 34

Pr-processamento em C / C++

#ifdef __linux__
//linux
#elif _WIN32
// windows
#else
//

outro

#endif

25 / 34

Padro de programao C
Ao desenvolver programas em C ou C++ siga o
recomendado no apndice 1 Padro de Composio de
Mdulos C e C++.
Todos os mdulos que podem ser includos devem conter
um controle de compilao nica
mdulo de definio
tabelas de definio
tabelas de dados
#if !defined( Nome-arquivo_MOD )
#define
Nome-arquivo_MOD
/* Comentrio cabealho do arquivo */
Corpo do arquivo
#endif
/* Comentrio fim de arquivo*/

26 / 34

Consistncia das interfaces, relembrana


Para garantir a consistncia entre mdulos cliente e
mdulos servidores, fundamental que se utilize
exatamente a mesma definio de interface tanto ao
compilar o mdulo servidor, como ao compilar os diversos
mdulos cliente deste mdulo servidor
O cdigo da interface redigido no mdulo de definio (.h)
ser incorporado atravs de #include
ao compilar o correspondente mdulo de implementao
ao compilar mdulos cliente deste mdulo.

27 / 34

Consistncia das interfaces C/C++


Problema devido a propriedades sintticas das linguagens
C/C++
variveis globais externas devem aparecer exatamente uma
vez sem o declarador extern
todas as outras vezes devem vir precedidas deste declarador

Pode-se conseguir isso com cdigo de pr-processamento


que assegure
sempre que um cliente compilar o mdulo de definio, as
declaraes de variveis globais externas estejam precedidas
de extern
sempre que o prprio mdulo compilar o mdulo de definio,
as variveis globais externas no estejam precedidas de
extern
28 / 34

Padro para o mdulo de definio


Inicie o cdigo do corpo do mdulo de definio com o
seguinte esquema de cdigo:
/* Controle de escopo do arquivo de definio */
#ifdef Nome-arquivo-modulo_OWN
#define Nome-arquivo-modulo_EXT
#else
#define Nome-arquivo-modulo_EXT extern
#endif

Ao final do cdigo do mdulo de definio coloque o cdigo:


#undef Nome-arquivo-modulo_EXT

29 / 34

Padro para o mdulo de definio


Declare cada varivel global externa no inicializada da
seguinte forma:
Nome-arquivo-modulo_EXT declarao-de-varivel ;

Declare cada varivel global externa inicializada da seguinte


forma
Nome-arquivo-modulo_EXT

declarao-variavel

#ifdef Nome-arquivo-modulo_OWN
= Inicializao ;
#else
;
#endif

30 / 34

Exemplo de mdulo de definio


#ifndef EXEMP_MOD
#define EXEMP_MOD
#ifdef EXEMP_OWN
#define EXEMP_EXT
#else
#define EXEMP_EXT extern
#endif
/***** Tipo de dados exportado pelo mdulo *****/
typedef struct
{
int UmInt ;
int OutroInt ;
} EX_tpMeuTipo ; /* declarao de tipos no afetada pelas regras */
/***** Estruturas de dados exportada pelo mdulo *****/
EXEMP_EXT int EX_vtNum[ 5 ]
#if defined( EXEMP_OWN )
= { 1 , 2 , 3 , 4 , 5 } ;
#else
;
#endif
#undef EXEMP_EXT
#endif
31 / 34

Padro para o mdulo de implementao


No mdulo de implementao redija o cdigo de incluso do
respectivo mdulo de definio na forma a seguir:
#define Nome-Arquivo-Modulo_OWN
#include "Nome-Arquivo-Modulo.H"
#undef

Nome-Arquivo-Modulo_OWN

Exemplo
/* Incluses do compilador /
#include <stdio.h>
/* Incluso do prprio mdulo de definio /
#define
EXEMP_OWN
#include "EXEMP.H"
#undef
EXEMP_OWN
/* Incluso de mdulos de definio de servidores */
#include "Modulo1.H"
#include "Modulo2.H"
#include "Tabela.INC"
. . .

32 / 34

Alternativa ao padro
Embora fora do nosso padro, a seguinte organizao
funciona tambm:
Mdulo de definio (.h ou .hpp)
extern int XX_VarInt ;

/* sempre com extern */

Mdulo de implementao (.c ou .cpp)


int XX_VarInt = 1000 ;

/* redeclarado sem o extern */

Esta organizao tem a vantagem de no necessitar os


elementos xxx_EXT, nem a forma convoluta (enrolada) de
declarar dados externados e inicializados.
Tem a desvantagem de exigir a alterao de vrios mdulos
caso seja feita alguma mudana em uma interface

33 / 34

Alternativa melhor ainda


No utilize variveis globais externas
Encapsule todas as variveis globais no mdulo de
implementao, exemplo
static int ZZZ ;
Acesse-as com funes de acesso declaradas no mdulo de
definio, exemplo
void AtribuirZZZ( int ZZZ ) ;
int ObterZZZ( void ) ;

34 / 34

Вам также может понравиться