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 -m32 -c -Wall temp1.c > gcc -m32 -c -Wall temp2.c > gcc -m32 -o prog temp1.o temp2.o(Você poderia fazer tudo de uma só vez chamando
gcc -m32 -Wall temp1.c temp2.c,
mas aí 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: google "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?
Restabeleça no arquivo temp1.c declaração int a = 1024;
temp2.c) a linha #include "temp1.h" por extern char a; Recompile e execute o programa.
O que aconteceu? Você consegue explicar?
extern char a; por char a = 0; e recompile o programa. O que acontece?
static char a = 0;,
o que acontece?
Certifique-se que você entendeu o que aconteceu! (Dê uma olhada nos símbolos de
cada módulo usando o nm).
Restaure a inclusão de "temp1.h" no 2o arquivo (temp2.c), e remova a declaração "local" static char a = 0;.
Agora remova no primeiro arquivo (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 e execute o programa.
(Atenção: Gere o executável com
gcc -m32 -o prog -Wa,--execstack temp1.c temp2.c) .
O que acontece?
Repita com o valor inicial de b sendo 0xC3.
O que acontece agora?
Certifique-se que você entendeu o que aconteceu nos dois casos!