Considere o programa formado pelos arquivos abaixo:
arquivo temp1.c:
#include <stdio.h>
#include "temp1.h"
#include "temp2.h"
int a = 1024;
int main (void) {
foo();
printf("%d\n", a);
return 0;
}
arquivo temp2.c:
#include "temp1.h"
#include "temp2.h"
int b = 10;
void foo (void) {
a = -3;
}
arquivo temp1.h:
extern int a;
arquivo temp2.h:
extern int b; void foo(void);
Note que os arquivos temp1.h e temp2.h
contém declarações dos simbolos globais exportados, respectivamente,
por temp1.c e temp2.c
A inclusão desses arquivos garante a consistência dessas declarações entre os
módulos, tanto para os arquivos que definem os símbolos quanto para os que
os importam.
> gcc -c -Wall temp1.c > gcc -c -Wall temp2.c > gcc -o prog temp1.o temp2.o(Você poderia fazer tudo de uma só vez chamando
gcc -Wall temp1.c temp2.c,
mas, neste caso, o gcc não gera os arquivos .o.)
Use o programa nm para inspecionar os símbolos
usados por cada módulo
(chame nm temp1.o e nm temp2.o).
Você consegue inferir o significado das letras que aparecem
na saída deste programa (U, T, etc.)?
(Dica: "man nm".)
Troque no 1o arquivo (temp1.c) a linha int a = 1024; por char a = 1; e recompile esse módulo.
O que acontece? Em que passo foi detetado o erro? (compilação? linkedição?)
Restabeleça no arquivo temp1.c declaração int a = 1024;
temp2.c) a linha #include "temp1.h" por extern char a;
Recompile os dois módulos, gere um novo executável e execute o programa. O que aconteceu? Você consegue explicar?
temp2.c a declaração
extern char a;
por int a = 1; e recompile este módulo.
Tente gerar um novo executável. O que acontece agora? Algum erro ocorreu?
(se sim, em um passo?)
Inspecione novamente os símbolos dos módulos objeto usando o nm.
static int a = 1;,
o que acontece? Por que?
Restaure a inclusão de "temp1.h" no 2o arquivo (temp2.c),
e remova a declaração static int a = 1;.
temp1.c) a linha #include "temp2.h" (isto é, a declaração dos símbolos exportados por temp2).
Troque em temp1.c
a linha foo(); por b();
Recompile os dois módulos e gere um novo executável com
gcc -Wa,--execstack -Wall -c temp1.c gcc -Wa,--execstack -Wall -c temp2.c gcc -o prog -Wa,--execstack temp1.o temp2.oVerifique com o
nm as tabelas de símbolo de cada módulo
(em especial, o símbolo b).
Execute o programa. O que aconteceu? Por que?
b em temp2.c
por 0xC3. Recompile este módulo, gere um novo executável, e execute-o.
O que acontece agora? Por que?