compilacion
Diferencias
Muestra las diferencias entre dos versiones de la página.
Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
compilacion [2012/09/06 12:53] – [Link] lmateu | compilacion [2014/09/04 13:42] (actual) – [Preproceso] lmateu | ||
---|---|---|---|
Línea 1: | Línea 1: | ||
- | ===== Fases de la Compilación ===== | + | ===== Etapas |
La compilación de un programa en C pasa por varias etapas desde | La compilación de un programa en C pasa por varias etapas desde | ||
Línea 49: | Línea 49: | ||
Recuerde que cada identificador que se usa en C debe haber sido declarado previamente, | Recuerde que cada identificador que se usa en C debe haber sido declarado previamente, | ||
modo se considera un error. | modo se considera un error. | ||
- | de un tipo en un archivo, pero de otro en otro archivo. | + | de un tipo en un archivo, pero de otro tipo en otro archivo. |
este caso porque simplemente no tiene la información para detectar el error. | este caso porque simplemente no tiene la información para detectar el error. | ||
se denomina compilación **separada**. | se denomina compilación **separada**. | ||
Línea 77: | Línea 77: | ||
% gcc -E prog.c | % gcc -E prog.c | ||
| | ||
- | La salida | + | La salida |
int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||
Línea 156: | Línea 156: | ||
| | ||
int f() { | int f() { | ||
+ | b= 1.0; | ||
return g(a); | return g(a); | ||
} | } | ||
Línea 169: | Línea 170: | ||
int main() { | int main() { | ||
int x= f(); | int x= f(); | ||
- | printf(" | + | printf(" |
return x; | return x; | ||
} | } | ||
| | ||
int g(int x) { | int g(int x) { | ||
+ | a= 2; | ||
return x; | return x; | ||
} | } | ||
Línea 180: | Línea 182: | ||
al ensablador que no reserve espacio para ella porque se trata de una promesa de que otro archivo | al ensablador que no reserve espacio para ella porque se trata de una promesa de que otro archivo | ||
la va a declarar. | la va a declarar. | ||
- | ' | + | ' |
- | | + | La fase de link en Unix la realiza el comando '' |
+ | un error histórico, porque su tarea no es la de un //loader// (cargardor). | ||
+ | es la componente del núcleo del sistema operativo que carga un archivo ejecutable en la memoria del | ||
+ | computador para que sea ejecutado. | ||
+ | se conserva quizás por compatibilidad. | ||
+ | |||
+ | | ||
Línea 228: | Línea 236: | ||
Las bibliotecas son archivos con la extensión ' | Las bibliotecas son archivos con la extensión ' | ||
- | de manejarlos como una unidad. | + | de manejarlos como una unidad. |
- | | + | |
+ | void g(); | ||
+ | |||
+ | void f() { | ||
+ | g(); | ||
+ | } | ||
- | Luego se pueden especificar en gcc: | + | /* bib2.c */ |
+ | void g() { | ||
+ | } | ||
- | | + | |
+ | void h() { | ||
+ | } | ||
- | Si los archivos | + | Compilamos ambos archivos |
- | contenido en bib.a, entonces se agrega ese archivo al binario. | + | |
- | Uno de los bugs más difíciles de diagnosticar que me ha tocado presenciar | + | % gcc -c bib1.c bib2.c bib3.c |
+ | |||
+ | Lo que genera los archivos bib1.o y bib2.o. | ||
+ | |||
+ | % ar r bib.a bib1.o bib2.o bib3.o | ||
+ | |||
+ | Ahora podemos usar f o g desde otro programa: | ||
+ | |||
+ | /* a.c */ | ||
+ | int main() { | ||
+ | f(); | ||
+ | } | ||
+ | |||
+ | Compilamos incluyendo la biblioteca con: | ||
+ | |||
+ | % gcc a.c bib.a | ||
+ | |||
+ | Como a.o incluye una referencia pendiente a f, el linker la busca en las bibliotecas y la encuentra | ||
+ | en bib1.o, por lo tanto agrega bib1.o completo al binario. | ||
+ | referencia pendiente a g y la encuentra en bib2.o al binario. | ||
+ | lado, el archivo bib3.o no se agrega al binario ejecutable. | ||
+ | |||
+ | Uno de los bugs más difíciles de diagnosticar que me ha tocado presenciar | ||
un función de biblioteca llamaba a otra función dentro de la misma biblioteca pero que casualmente | un función de biblioteca llamaba a otra función dentro de la misma biblioteca pero que casualmente | ||
se llamaba igual que una variable global de los fuentes. | se llamaba igual que una variable global de los fuentes. | ||
Línea 245: | Línea 283: | ||
¡El programa se caía con un segmentation fault inexplicable! | ¡El programa se caía con un segmentation fault inexplicable! | ||
+ | Esto se puede reproducir cambiando a.c por: | ||
+ | |||
+ | /* a.c */ | ||
+ | float g= 3.14; | ||
+ | int main() { | ||
+ | f(); | ||
+ | } | ||
+ | Ejercicio: Compile y ejecute para observar el segmentation fault. | ||
+ | la ejecución hacia la variable en punto flotante g, como si ahí hubiesen instrucciones. |
compilacion.1346936009.txt.gz · Última modificación: 2012/09/06 12:53 por lmateu