@c %**end of header @iftex @finalout @end iftex @setchapternewpage odd @titlepage @title Una Introducci@'on a GCC @subtitle para los Compiladores de GNU @code{gcc} y @code{g++} @subtitle Revisado y actualizado @author Brian Gough @author Prefacio por Richard M.@: Stallman @page @vskip 0pt plus 1filll @ifset publish @flushleft El registro de este libro est@'a disponible en la Biblioteca Brit@'anica. Segunda impresi@'on, Agosto 2005 (1/8/2005). Revisado y actualizado. Primera impresi@'on, Marzo 2004 (7/3/2004). Traducido por David Arroyo Men@'endez y Luis Palomo de On@'{@dotless{i}}s Guti@'errez, Agosto 2011 (10/8/2011). Revisado y actualizado (gcc 4.6). Publicado por Network Theory Limited.15 Royal Park Bristol BS8 3AL United Kingdom Correo electr@'onico: info@@network-theory.co.uk ISBN 0-9541617-9-3 Hay m@'as informaci@'on de este libro disponible desde @uref{http://www.network-theory.co.uk/gcc/intro/} @end flushleft @vskip 1ex Imagen de cubierta: Del dise@~no de una pila de hardware r@'apida y eficiente energ@'eticamente.@footnote{``A Fast and Energy-Efficient Stack'' por J.@: Ebergen, D.@: Finchelstein, R.@: Kao, J.@: Lexau y R.@: Hopkins.} Imagen creada con el sistema de dise@~no libre Electric VLSI escrito por Steven Rubin de Static Free Software (@uref{http://www.staticfreesoft.com/,,www.staticfreesoft.com}). Static Free Software proporciona soporte para Electric en la industria del dise@~no electr@'onico @vskip 1ex @end ifset Copyright @copyright{} 2004, 2005 Network Theory Ltd. Se permite la copia, distribuci@'on y/o modificaci@'on de este documento bajo los t@'erminos de la Licencia de Documentaci@'on Libre de GNU, Versi@'on 1.2 o cualquier versi@'on posterior publicada por la Free Software Foundation; sin Secciones Invariantes, con el Texto de Portada diciendo ``Un Manual de Network Theory'', y con el Texto de Contraportada como en (a). Una copia de la licencia est@'a incluida en la secci@'on titulada ``GNU Free Documentation License''. (a) El Texto de Contraportada es: ``El desarrollo de este manual fu@'e realizado enteramente por Network Theory Ltd. Las copias publicadas por Network Theory Ltd traer@'an dinero para m@'as documentaci@'on libre.'' @ifset printed Las fuentes en Texinfo para este manual pueden ser obtenidas de @* @code{http://www.network-theory.co.uk/gcc/intro/src/} @end ifset @end titlepage @contents @node Top @top Una Introducci@'on a GCC Este manual proporciona una introducci@'on a los Compiladores de GNU de C y C++, @code{gcc} y @code{g++}, que son parte de la Colecci@'on de Compiladores de GNU (GCC). El desarrollo de este manual fu@'e realizado enteramente por @uref{http://www.network-theory.co.uk/,Network Theory Ltd}. Las copias publicadas por Network Theory Ltd traer@'an dinero para m@'as documentaci@'on libre. @menu * Prefacio:: * Introducci@'on:: * Compilando un programa C:: * Opciones de compilaci@'on:: * Usando el preprocesador:: * Compilando para depuraci@'on:: * Compilando con optimizaci@'on:: * Compilando un programa C++:: * Opciones espec@'{@dotless{i}}ficas de plataforma:: * Resoluci@'on de problemas:: * Utilidades relativas al compilador:: * Como funciona el compilador:: * Examinado archivos compilados:: * Mensajes comunes de error:: * Obteniendo ayuda:: * Lectura adicional:: * Reconocimientos:: * Organizaciones de software libre:: * @'Indice:: @end menu @ifnotinfo @node Prefacio @unnumbered Prefacio @i{Este Prefacio es una amable contribuci@'on de Richard M. Stallman, el principal autor de GCC y fundador del Proyecto GNU.} @vskip 1ex Este libro es una gu@'{@dotless{i}}a para iniciarse en GCC, GNU Compiler Collection (Colecci@'on de Compiladores GNU). Se mostrar@'a c@'omo usar GCC como una herramienta de programaci@'on. GCC es una herramienta de programaci@'on, esto es verdad--- pero tambi@'en es algo m@'as. Tambi@'en forma parte de la campa@~na por la libertad de los usuarios de ordenadores desde hace m@'as de 20 a@~nos. Todo lo que queremos es buen software, pero @questiondown{}qu@'e significa para nosotros que un software sea bueno?. Funcionalidades adecuadas y fiabilidad puede ser algo @emph{t@'ecnicamente} bueno, pero esto no es suficiente. Un buen software debe adem@'as ser @emph{@'eticamente} bueno: tiene que ser respetuoso con la libertad de los usuarios. Como usuario de software, se deber@'{@dotless{i}}a tener el derecho a ejecutarlo como se necesite, el derecho a estudiar el c@'odigo fuente y a cambiarlo como se desee, el derecho a redistribuir copias de @'este a terceras personas, y el derecho a publicar versiones modificadas con lo que se puede contribuir a la construcci@'on de la comunidad. Cuando un programa respeta la libertad de esta forma, se dice que es @dfn{software libre}. Anteriormente a GCC hab@'{@dotless{i}}a otros compiladores para C, Fortran, Ada, etc. Pero no eran software libre, y no se pod@'{@dotless{i}}an usar libremente. Escrib@'{@dotless{i}} el GCC para que se pueda usar un compilador sin perder nuestra libertad. Un compilador solo no es suficiente ---para usar un sistema de computaci@'on, se debe disponer de un sistema operativo completo. En 1983, todos los sistemas operativos para ordenadores modernos eran no libres. Para remediar esto, en 1984 comenc@'e a desarrollar el sistema operativo GNU, un sistema similiar a Unix que ser@'{@dotless{i}}a software libre. El desarrollo de GCC fu@'e una parte del desarrollo de GNU. A principios de los 90, el reci@'en terminado sistema operativo GNU fu@'e completado con la suma de un kernel, Linux, que se hizo software libre en 1992. El sistema operativo combinado GNU/Linux ha alcanzado la meta de hacer posible el uso de una computadora en libertad. Pero la libertad nunca est@'a autom@'aticamente asegurada, y debemos trabajar para protegerla. El Movimiento del Software Libre necesita tu apoyo. @vskip 1ex @flushright Richard M.@: Stallman Febrero de 2004 @end flushright @end ifnotinfo @node Introducci@'on @chapter Introducci@'on El prop@'osito de este libro es explicar el uso de los compiladores de GNU C y C++, @code{gcc} y @code{g++}. Despu@'es de leer este libro se comprender@'a como compilar un programa y, c@'omo usar las opciones b@'asicas del compilador para optimizaci@'on y depuraci@'on. Este libro no intenta ense@~nar los lenguajes C o C++ en s@'{@dotless{i}}, este material puede ser encontrado en muchos otros lugares (@pxref{Lectura adicional}). Los programadores experimentados que est@'an familiarizados con otros sistemas, pero son nuevos en compiladores GNU, pueden saltarse las primeras secciones de los cap@'{@dotless{i}}tulos ``@cite{Compilando un programa C}'', ``@cite{Usando el preprocesador}'' y ``@cite{Compilando un programa C++}''. Las secciones y cap@'{@dotless{i}}tulos restantes proporcionan una buena visi@'on del conjunto de las funcionalidades de GCC para aquellos que ya saben c@'omo usar otros compiladores. @menu * Una breve historia de GCC:: * Importantes caracter@'{@dotless{i}}sticas de GCC:: * Programaci@'on en C y C++:: * Convenciones usadas en este manual:: @end menu @node Una breve historia de GCC @section Una breve historia de GCC @cindex @code{gcc}, GNU C Compiler @cindex C, compilador @code{gcc} @cindex historia, de GCC @cindex Richard Stallman, principal autor de GCC @cindex Proyecto GNU, historia de @cindex Free Software Foundation (FSF) El autor original del Compilador de C de GNU (GCC) es Richard Stallman, el fundador del Proyecto GNU. El Proyecto GNU fu@'e iniciado en 1984 para crear un sistema operativo basado en software libre similar a UNIX y, as@'{@dotless{i}} promover la libertad y la cooperaci@'on entre usarios de ordenadores y programadores. Cualquier sistema operativo basado en UNIX necesita un compilador de C, y no hab@'{@dotless{i}}a compiladores libres en ese momento, el Proyecto GNU deb@'{@dotless{i}}a desarrollar uno desde cero. Este trabajo fu@'e financiado por donaciones de individuos y compa@~nias a trav@'es de la Free Software Foundation, una organizaci@'on sin @'animo de lucro destinada a dar soporte al trabajo del Proyecto GNU. La primera entrega de GCC fu@'e hecha en 1987. Esto fu@'e un significativo progreso, siendo el primer compilador portable para optimizar ANSI C liberado como software libre. Desde este momento GCC ha llegado a ser uno de las m@'as importantes herramientas en el desarrollo de software libre. @cindex C++, compilador @code{g++} @cindex @code{g++}, GNU C++ Compiler @cindex EGCS (Experimental GNU Compiler Suite) Un avance importante en el compilador llega con la serie 2.0 en 1992, que a@~nade la capacidad de compilar C++. En 1997, se cre@'o una rama experimental del compilador (EGCS) para mejorar la optimizaci@'on y el soporte de C++. Despu@'es de este trabajo, EGCS fu@'e adoptado como la principal l@'{@dotless{i}}nea de desarrollo de GCC y, estas funcionalidades llegaron a estar ampliamente disponibles en la versi@'on 3.0 de GCC en 2001. @cindex Fortran, compilador @code{g77} @cindex Objective-C @cindex ADA, compilador @code{gnat} @cindex Java, compilador @code{gcj} @cindex @code{g77}, compilador de Fortran @cindex @code{gnat}, compilador GNU de ADA @cindex @code{gcj}, GNU Compiler for Java A trav@'es del tiempo GCC ha sido extendido para dar soporte a muchos lenguajes adicionales, incluyendo Fortran, ADA, Java y Objective-C. El acr@'onimo GCC es ahora usado para referir al ``GNU Compiler Collection'' (Colecci@'on de Compiladores de GNU). Su desarrollo est@'a guiado por el @dfn{GCC Steering Committee}, un grupo compuesto de representantes de las comunidades de usuarios/as de GCC en la industria, la investigaci@'on y la academia. @node Importantes caracter@'{@dotless{i}}sticas de GCC @section Importantes caracter@'{@dotless{i}}sticas de GCC @cindex funcionalidades, de GCC @cindex principales funcionalidades, de GCC @cindex Compiladores de GNU, principales funcionalidades Esta secci@'on describe algunas de las m@'as importantes funcionalidades de GCC. Lo primero de todo, GCC es un compilador portable ---se ejecuta en la mayor@'{@dotless{i}}a de las plataformas disponibles hoy, y puede producir salidas para muchos tipos de procesadores. Adem@'as de procesadores usados en ordenadores personales, tambi@'en soporta microcontroladores, DSPs y CPUs de 64 bits. @cindex sistemas embebido, para compilaci@'on cruzada GCC no es solo un compilador nativo ---tambi@'en puede @dfn{compilar cruzado} cualquier programa, produciendo ficheros ejecutables para un sistema diferente desde el que GCC est@'a siendo usado. Esto permite compilar software para sistemas embebidos que no son capaces de ejecutar un compilador. GCC est@'a escrito en C con un fuerte enfoque hacia la portabilidad, y puede compilarse a s@'{@dotless{i}} mismo, as@'{@dotless{i}} puede ser adaptado a nuevos sistemas f@'acilmente. GCC tiene m@'ultiples @dfn{frontends}, para parsear diferentes lenguajes. Los programas en cada lenguaje pueden ser compilados, o compilados de manera cruzada, para cualquier arquitectura. Por ejemplo, un programa en ADA puede ser compilado para un microcontrolador, o un programa en C para un supercomputador. GCC tiene un dise@~no modular, permitiendo que el soporte para nuevos lenguajes y arquitecturas sea a@~nadido. A@~nadir un nuevo front-end a GCC habilita el uso de este lenguaje en cualquier arquitectura y proporciona que est@'en disponibles facilidades (tales como librer@'{@dotless{i}}as) en tiempo de ejecuci@'on. De manera similar, si se a@~nade soporte para una nueva arquitectura @'este se vuelve disponible para todos los lenguajes. Finalmente, y de manera m@'as importante, GCC es software libre, distribuido bajo la GNU General Public License (GNU GPL).@footnote{Para detalles ver el fichero de licencia @file{COPYING} distribuido con GCC.} Esto significa que se tiene la libertad para usar y modificar GCC, como con todo el software de GNU. Si se necesita soporte para un nuevo tipo de CPU, un nuevo lenguaje, o una nueva funcionalidad es posible a@~nadirla uno mismo o contratar a alguien para mejorar GCC de manera personalizada. Se puede contratar a alguien para arreglar un error si esto es importante en el trabajo cotidiano. M@'as all@'a, hay libertad para compartir cualquier mejora hecha a GCC. Como resultado de esta libertad, se pueden usar las mejoras hechas a GCC por otras personas. Las muchas funcionalidades ofrecidas por GCC hoy muestran c@'omo esta libertad de cooperar funciona en tu beneficio, y en el de cualquiera que use GCC. @node Programaci@'on en C y C++ @section Programaci@'on en C y C++ @cindex Lisp, comparado con C/C++ @cindex Smalltalk, comparado con C/C++ @cindex Scheme, comparado con C/C++ @cindex Java, comparado con C/C++ @cindex C/C++, riesgos de uso @cindex riesgos, ejemplos de C y C++ son lenguajes que permiten acceso directo a la memoria del ordenador. Hist@'oricamente, han sido usados para escribir sistemas software de bajo nivel, y aplicaciones d@'onde el alto rendimiento o el control a trav@'es del uso de recursos son cr@'{@dotless{i}}ticos. Sin embargo, se requiere de gran cuidado para asegurar que la memoria es accedida de manera correcta, para evitar la corrupci@'on de otras estructuras de datos. Este libro describe t@'ecnicas que ayudar@'an a detectar potenciales errores durante la compilaci@'on, pero los riesgos de usar lenguajes como C o C++ nunca pueden ser eliminados. Adem@'as de C y C++ el Proyecto GNU tambi@'en proporciona otros lenguajes de alto nivel, tales como GNU Common Lisp (@code{gcl}), GNU Smalltalk (@code{gst}), el GNU Scheme extension language (@code{guile}) y el GNU Compiler para Java (@code{gcj}). Estos lenguajes no permiten al usuario acceder a memoria directamente, eliminando la posibilidad de errores de acceso a memoria. Son una alternativa segura a C y C++ para muchas aplicaciones. @node Convenciones usadas en este manual @section Convenciones usadas en este manual @cindex convenciones, usadas en manual @cindex ejemplos, convenciones usadas @cindex prompt de shell @cindex @code{$}, prompt de shell Este manual contiene muchos ejemplos que pueden ser escritos en el teclado. Un comando introducido en el terminal se muestra como esto, @example $ @i{comando} @end example @noindent seguido por su salida. Por ejemplo: @example $ echo "hola mundo" hola mundo @end example @noindent @cindex signo del d@'olar @code{$}, shell prompt El primer car@'acter en la l@'{@dotless{i}}nea es el prompt del terminal, y no ser@'a escrito. El signo del d@'olar @samp{$} es usado como el prompt est@'andar en este manual, aunque en algunos sistemas puede usar un car@'acter diferente. Cuando un comando en un ejemplo es demasiado largo para ajustarse en una sola l@'{@dotless{i}}nea es envuelto e indentado en las l@'{@dotless{i}}neas subsiguientes, como este: @example $ echo "un ejemplo de una l@'{@dotless{i}}nea que es demasiado larga para este manual" @end example @noindent Cuando se introduce en el teclado, el comando entero ser@'a escrito en una sola l@'{@dotless{i}}nea. Los ficheros fuente de ejemplo usados en este manual pueden ser descargados desde el sitio web de la editorial,@footnote{Ver @uref{http://www.network-theory.co.uk/gcc/intro/}} o introducidos a mano usando cualquier editor de texto, tal como el editor est@'andar de GNU, @code{emacs}. Los comandos de compilaci@'on de ejemplo usan @code{gcc} y @code{g++} como los nombres de los compiladores de GNU de C y de C++ y usan @code{cc} para referirse a otros compiladores. Los programas de ejemplo trabajar@'an con cualquier versi@'on de GCC. Las opciones de estos comandos que est@'an disponibles en versiones recientes de GCC son anotadas en el texto. @cindex variables de shell @cindex variables de entorno Este ejemplo asume el uso de un sistema operativo GNU ---hay peque@~nas diferencias en la salida en otros sistemas. Algunos mensajes de salida no esenciales y dependientes del sistema (tal como rutas muy largas) han sido editadas en los ejemplos por brevedad. Los comandos para configurar variables de entorno usan la sintaxis de la shell est@'andar de GNU (@code{bash}), y funcionar@'a con cualquier versi@'on de Bourne shell. @node Compilando un programa C @chapter Compilando un programa C @cindex compilando programas C con @code{gcc} Este cap@'{@dotless{i}}tulo describe c@'omo compilar programas C usando @code{gcc}. Los programas pueden ser compilados desde un solo fichero fuente o desde m@'ultiples ficheros fuente, y pueden usar librer@'{@dotless{i}}as de sistema y ficheros de cabecera. @cindex c@'odigo fuente @cindex c@'odigo m@'aquina @cindex fichero ejecutable @cindex fichero binario, tambi@'en llamado fichero ejecutable La compilaci@'on se refiere al proceso de convertir un programa desde el @dfn{c@'odigo fuente} textual de un lenguaje de programaci@'on tal como C o C++, en @dfn{c@'odigo m@'aquina}, la secuencia de unos y ceros usados para controlar la unidad central de proceso (CPU) del ordenador. Este c@'odigo m@'aquina es almacenado en un fichero conocido como @dfn{fichero ejecutable}, a veces tambi@'en llamado @dfn{fichero binario}. @menu * Compilando un peque@~no programa C:: * Encontrando errores en un peque@~no programa:: * Compilando m@'ultiples archivos fuentes:: * Compilando archivos independientes:: * Recompilando y reenlazando:: * Un peque@~no makefile:: * Enlazando con librer@'{@dotless{i}}as externas:: * Usando librer@'{@dotless{i}}as de archivos de cabeceras:: @end menu @node Compilando un peque@~no programa C @section Compilando un peque@~no programa C @cindex Hola Mundo, programa en C @cindex C, compilando con @code{gcc} @cindex programa C simple, compilando El cl@'asico programa de ejemplo para el lenguaje C es @dfn{Hola Mundo}. Aqu@'{@dotless{i}} est@'a el c@'odigo fuente para nuestra versi@'on del programa: @example @verbatiminclude hola.es.c @end example @noindent @cindex @code{.c}, extensi@'on de fichero fuente C @cindex @code{c}, extensi@'on de fichero fuente C @cindex fichero fuente C, extensi@'on @code{.c} @cindex extensi@'on de fichero, fichero fuente @code{.c} @cindex extensi@'on, fichero fuente @code{.c} Se asume que el c@'odigo fuente est@'a almacenado en un fichero llamado @file{hola.es.c}. Para compilar el fichero @file{hola.es.c} con @code{gcc}, se puede usar el siguiente comando: @example $ gcc -Wall hola.es.c -o hola @end example @noindent @cindex @code{gcc}, ejemplo simple @cindex @option{-o}, opci@'on para asignar el nombre del fichero de salida @cindex @option{o}, opci@'on para asignar el nombre del fichero de salida @cindex opci@'on para asignar fichero de salida, @option{-o} @cindex @code{a.out}, nombre del fichero ejecutable por defecto @cindex ejecutable, nombre de fichero por defecto @code{a.out} @cindex nombre del fichero ejecutable por defecto, @code{a.out} Esto compila el c@'odigo fuente de @file{hola.es.c} a c@'odigo m@'aquina y lo almacena en el fichero ejecutable @file{hola}. El fichero de salida para el c@'odigo m@'aquina se especifica usando la opci@'on @option{-o}. Esta opci@'on normalmente es el @'ultimo argumento en la l@'{@dotless{i}}nea de comandos. Si se omite, la salida es escrita a un fichero por defecto llamado @file{a.out}. N@'otese que si ya existe un fichero con el mismo nombre que el fichero ejecutable en el directorio actual, entonces se sobreescribir@'a. @cindex @option{-Wall}, opci@'on que habilita los avisos comunes @cindex @option{Wall}, opci@'on que habilita los avisos comunes @cindex opciones de aviso, @option{-Wall} La opci@'on @option{-Wall} activa todos los avisos m@'as comunes ---@strong{@exclamdown{}se recomienda usar siempre esta opci@'on!}. Hay muchas otras opciones de avisos que ser@'an discutidas en cap@'{@dotless{i}}tulos posteriores, pero @option{-Wall} es la m@'as importante. GCC no producir@'a avisos a menos que est@'en activados. Los avisos del compilador son una ayuda esencial detectando problemas al programar en C y C++. En este caso, el compilador no produce avisos con la opci@'on @option{-Wall}, debido a que el programa es completamente v@'alido. El c@'odigo fuente que no produce avisos se dice que @dfn{compila limpiamente}. @cindex ejecutable, funcionando @cindex ejecutando un fichero binario, C Para ejecutar el programa, escribe la ruta del ejecutable as@'{@dotless{i}}: @example $ ./hola @exclamdown{}Hola, mundo! @end example @noindent Esto carga el fichero ejecutable en memoria y hace que la CPU empiece a ejecutar las instrucciones que contiene. La ruta @code{./} se refiere al directorio actual, as@'{@dotless{i}} @code{./hola} carga y ejecuta el fichero ejecutable @file{hola} localizado en el directorio actual. @node Encontrando errores en un peque@~no programa @section Encontrando errores en un peque@~no programa @cindex @code{printf}, ejemplo de error por formato Como se mencion@'o antes, los avisos del compilador son una ayuda esencial cuando se programa en C y C++. Para demostrar esto, el programa de debajo contiene un peque@~no error: usa la funci@'on @code{printf} de manera incorrecta, especificando un formato en coma flotante @samp{%f} para un valor entero: @example @verbatiminclude mal.es.c @end example @noindent Este error no es obvio a primera vista, pero puede ser detectado por el compilador si la opci@'on de aviso @option{-Wall} se ha habilitado. Al compilar el anterior programa, @file{mal.es.c}, con la opci@'on @option{-Wall} produce el siguiente mensaje: @cindex aviso, formato de diferente tipo que el argumento @cindex formato, aviso de tipo diferente en el argumento @cindex argumento de diferente tipo, aviso de formato @example $ gcc -Wall bad.c -o bad bad.c: In function 'main': bad.c:6:3: warning: format '%f' expects argument of type 'double', but argument 2 has type 'int' [-Wformat] @end example @noindent Esto indica que un formato de cadena ha sido usado incorrectamente en el fichero @file{mal.es.c} en la l@'{@dotless{i}}nea 6. Los mensajes producidos por GCC siempre tienen la forma @i{fichero:n@'umero de l@'{@dotless{i}}nea:mensaje}. El compilador distingue entre @dfn{mensajes de error}, que impiden una compilaci@'on exitosa, y @dfn{mensajes de aviso} que indican posibles problemas (pero no detienen la compilaci@'on). En este caso, el especificador de formato ser@'a @samp{%d} para un argumento entero. Los especificadores de formato permitidos para @code{printf} pueden ser encontrados en cualquier libro general de C, tal como el @cite{GNU C Library Reference Manual} (@pxref{Lectura adicional}). Sin la opci@'on de aviso @option{-Wall} el programa compila limpiamente, pero produce resultados incorrectos: @cindex error, ejemplo de @example $ gcc mal.es.c -o mal $ ./mal Dos y dos son 0.000000 @r{(salida incorrecta)}@end example @noindent @cindex C/C++, riesgos de uso @cindex riesgos, ejemplos de El incorrecto formato especificado causa que la salida est@'e corrompida, porque a la funci@'on @code{printf} se le pasa un entero en lugar de un n@'umero en coma flotante. Los n@'umeros enteros y en coma flotante son almacenados en diferentes formatos en memoria, por lo general ocupan diferente n@'umero de bytes, obteniendo un falso resultado. La actual salida que se muestra puede diferir, dependiendo de la plataforma y el entorno espec@'{@dotless{i}}ficos. Claramente, es muy peligroso desarrollar un programa sin comprobar los avisos de compilaci@'on. Si hay alguna funci@'on no usada correctamente, causar@'a que el programa falle o produzca resultados incorrectos. Activando los avisos del compilador con la opci@'on @option{-Wall} se detectar@'an muchos de los m@'as habituales errores que ocurren programando en C. @node Compilando m@'ultiples archivos fuentes @section Compilando m@'ultiples archivos fuentes @cindex m@'ultiples ficheros, compilando @cindex compilando m@'ultiples ficheros Un programa puede ser dividido en m@'ultiples ficheros. Facilitando tanto la edici@'on como la comprensi@'on del c@'odigo, especialmente en el caso de largos programas ---tambi@'en permite que las partes individuales sean compiladas de manera independiente. En el siguiente ejemplo se dividir@'a el programa @dfn{Hola Mundo} en tres ficheros: @file{main.es.c}, @file{hola_fn.es.c} y el fichero de cabecera @file{hola.es.h}. Aqu@'{@dotless{i}} est@'a el programa principal @file{main.es.c}: @example @verbatiminclude main.es.c @end example @noindent La llamada original a la funci@'on de sistema @code{printf} en el programa previo @file{hola.es.c} ha sido reemplazado por una llamada a una nueva funci@'on externa @code{hola}, que se definir@'a en un fichero separado @file{hola_fn.es.c} @cindex declaraci@'on, en fichero de cabecera @cindex fichero de cabecera, declaraciones @cindex @code{.h}, extensi@'on de fichero de cabecera @cindex @code{h}, extensi@'on de fichero de cabecera @cindex fichero de cabecera, extensi@'on @code{.h} @cindex extensi@'on de fichero, @code{.h} fichero de cabecera @cindex extensi@'on, fichero de cabecera @code{.h} El programa main tambi@'en incluye el fichero de cabecera @file{hola.es.h} que contendr@'a la declaraci@'on de la funci@'on @code{hola}. La declaraci@'on es usada para asegurar que los tipos de los argumentos y el valor de retorno concuerda correctamente con la llamada de la funci@'on y la definici@'on de la funci@'on. No se necesita incluir el fichero de cabecera @file{stdio.h} en @file{main.es.c} para declarar la funci@'on @code{printf}, ya que el fichero @file{main.es.c} no llama a @code{printf} directamente. La declaraci@'on en @file{hola.es.h} es una simple l@'{@dotless{i}}nea que especifica el prototipo de la funci@'on @code{hola} @example @verbatiminclude hola1.es.h @end example @noindent La definici@'on de la funci@'on @code{hola} en s@'{@dotless{i}} est@'a contenida en el fichero @file{hola_fn.es.c}: @example @verbatiminclude hola_fn.es.c @end example @noindent Esta funci@'on imprime el mensaje ``@code{@exclamdown{}Hola, }@var{nombre} @code{!}'' usando como valor de @var{nombre} el argumento introducido. @cindex @code{#include}, directiva del preprocesador Casualmente, la diferencia entre las dos formas de la instrucci@'on de inclusi@'on @code{#include "@var{FILE}.h"} y @code{#include <@var{FILE}.h>} es que la primera busca el archivo @file{@var{FILE}.h} en el directorio actual antes de buscarlo en los directorios de los archivos de cabeceras del sistema. La instrucci@'on de inclusi@'on @code{#include <@var{FILE}.h>} busca por defecto los archivos de cabeceras del sistema, pero no busca en el directorio actual. Para compilar estos ficheros fuente con @code{gcc}, se usa el siguiente comando: @example $ gcc -Wall main.es.c hola_fn.es.c -o nuevohola @end example @noindent En este caso, se usa la opci@'on @option{-o} para especificar un nombre al fichero de salida diferente para el ejecutable, @file{nuevohola}. N@'otese que el fichero de cabecera @file{hola.es.h} no est@'a especificado en la lista de ficheros en la l@'{@dotless{i}}nea de comandos. La directiva @code{#include "hola.es.h"} en los ficheros fuente ordena al compilador incluirlo de forma autom@'atica en los puntos apropiados. Para ejecutar el programa, se escribe la ruta del ejecutable: @example $ ./nuevohola @exclamdown{}Hola, mundo! @end example @noindent Todas las partes del programa han sido combinadas en un solo fichero ejecutable, que produce el mismo resultado que el ejecutable creado desde el fichero fuente usado anteriormente. @node Compilando archivos independientes @section Compilando archivos independientes @cindex compilando ficheros de manera independiente @cindex independiente compilaci@'on de ficheros Si un programa es almacenado en un solo fichero, entonces cualquier cambio en una funci@'on individual requiere que el programa entero sea recompilado para producir un nuevo ejecutable. La recompilaci@'on de largos ficheros fuente puede consumir mucho tiempo. @cindex enlace, explicaci@'on de @cindex fichero objeto, explicaci@'on de @cindex @code{.o}, extensi@'on de fichero objeto @cindex @code{o}, extensi@'on de fichero objeto @cindex extensi@'on de fichero, fichero objeto @code{.o} @cindex extensi@'on, fichero objeto @code{.o} @cindex fichero objeto, extensi@'on @code{.o} Cuando los programas son almacenados en ficheros fuente independientes, solo los ficheros que han cambiado necesitan ser recompilados despu@'es de que el c@'odigo fuente haya sido modificado. De este modo, los ficheros fuente son compilados separadamente y @dfn{enlazados} juntos ---es un proceso de dos fases. En la primera fase, un fichero es compilado sin crear el ejecutable. El resultado es un @dfn{fichero objeto}, y tiene la extensi@'on @file{.o} al usar GCC. En la segunda fase, los ficheros objeto son unidos por otro programa llamado @dfn{enlazador}. El enlazador combina todos los ficheros objeto creando un solo ejecutable. Un fichero objeto contiene c@'odigo m@'aquina en el cual las referencias a direcciones de memoria de funciones (@'o variables) de otros ficheros se dejan indefinidas. Esto permite que los ficheros fuentes se compilen sin referencia directa a otros. El enlazador rellena estas direcciones perdidas cuando produce el ejecutable. @menu * Creando archivos objeto desde archivos fuente:: * Creando ejecutables desde archivos objeto:: @end menu @node Creando archivos objeto desde archivos fuente @subsection Creando archivos objeto desde archivos fuente @cindex creando ficheros objeto desde ficheros fuente @cindex @option{-c}, opci@'on para compilar a fichero objeto @cindex @option{c}, opci@'on para compilar a fichero objeto @cindex compila a fichero objeto, opci@'on @option{-c} @cindex fichero objeto, creando desde las fuentes usando la opci@'on @option{-c} La opci@'on @option{-c} es usada para compilar un fichero fuente para crear un fichero objeto. Por ejemplo, el siguiente comando compilar@'a el fichero fuente @file{main.es.c} para generar un fichero objeto: @example $ gcc -Wall -c main.es.c@end example @noindent Esto produce un fichero objeto @file{main.o} que contiene el c@'odigo m@'aquina para la funci@'on @code{main}. @'Este contiene una referencia la funci@'on externa @code{hola}, pero la correspondiente direcci@'on de memoria se deja indefinida en el fichero objeto en esta fase (se introducir@'a despu@'es al enlazarse). El correspondiente comando para compilar la funci@'on @code{hola} en el c@'odigo fuente @file{hola_fn.es.c} es: @example $ gcc -Wall -c hola_fn.es.c @end example @noindent Esto produce el fichero objeto @file{hola_fn.o}. N@'otese que no hay necesidad de usar la opci@'on @option{-o} para especificar el nombre del fichero de salida en este caso. Al compilar con la opci@'on @option{-c} el compilador de forma autom@'atica crea un fichero objeto cuyo nombre es el mismo que el fichero fuente, pero con @file{.o} en vez de la extensi@'on original. @cindex fichero de cabecera, no compilado No hay necesidad de poner el fichero de cabecera @file{hola.es.h} en la l@'{@dotless{i}}nea de comandos, ya que se incluye de forma autom@'atica gracias a las sentencias @code{#include} en @file{main.es.c} y @file{hola_fn.es.c}. @node Creando ejecutables desde archivos objeto @subsection Creando ejecutables desde archivos objeto @cindex creando ficheros ejecutables desde ficheros objeto @cindex enlazando, creando ficheros ejecutables desde ficheros objeto @cindex ejecutable, creando ficheros objeto al enlazar @cindex ficheros objeto, enlazando para crear un fichero ejecutable El paso final para crear un fichero ejecutable es usar @code{gcc} para enlazar los ficheros objetos juntos y llenar las direcciones perdidas de funciones externas. Para enlazar ficheros objetos juntos, simplemente se listan en el siguiente comando: @example $ gcc main.o hola_fn.o -o hola @end example @noindent Esta es una de las pocas ocasiones en las que no hay necesidad de usar la opci@'on de avisos @option{-Wall}, debido a que los ficheros fuente individuales han sido compilados exitosamente en c@'odigo objeto. Una vez que los ficheros fuente han sido compilados, enlazar es un proceso ambiguo que tendr@'a @'exito o fallar@'a (falla solo si hay referencias que no pueden ser resueltas). @cindex enlazador, descripci@'on inicial Para realizar el paso de enlazar @code{gcc} usar el enlazador @code{ld}, que es un programa separado. En sistemas GNU se usa el enlazador de GNU, GNU @code{ld}. Otros sistemas pueden usar el enlazador de GNU con GCC, o pueden tener sus propios enlazadores. El enlazador en s@'{@dotless{i}} ser@'a discutido despu@'es (@pxref{Como funciona el compilador}). Al ejecutar el enlazador, @code{gcc} crea un fichero ejecutable desde los ficheros objeto. @c @example @c ld main.o hello.o -o hello @c @end example El fichero ejecutable resultante puede ejecutarse ahora: @example $ ./hola @exclamdown{}Hola, mundo! @end example @noindent Se produce la misma salida que en la versi@'on del programa que usa un solo fichero fuente visto en la secci@'on previa. @node Recompilando y reenlazando @section Recompilando y reenlazando @cindex recompilando ficheros fuente modificados @cindex reenlazando ficheros objeto actualizados @cindex ficheros fuente modificados, recompilando @cindex ficheros objeto actualizados, reenlazando @cindex ficheros fuente, recompilando @cindex ficheros objeto, reenlazando @cindex programas C, recompilando despu@'es de modificarse Para mostrar c@'omo los ficheros fuente pueden ser compilados de manera independiente se editar@'a el programa @file{main.es.c} para imprimir un saludo para @code{cualquiera} en vez de @code{mundo}: @example @verbatiminclude main2.es.c @end example @noindent El fichero actualizado @file{main.es.c} ahora puede ser recompilado con el siguiente comando: @example $ gcc -Wall -c main2.es.c@end example @noindent @cindex recompilando ficheros fuente modificados @cindex ficheros fuente modificados, recompilando @cindex ficheros fuente actualizados, recompilando Esto produce un nuevo fichero objeto @file{main.o}. No se necesita crear un nuevo fichero objeto para @file{hola_fn.es.c}, debido a que el fichero y los ficheros relacionados de los que depende, tales como ficheros de cabeceras, no han cambiado. @cindex reenlazando ficheros objeto actualizados @cindex enlazando, ficheros objeto actualizados El nuevo fichero objeto puede ser reenlazado con la funci@'on @code{hola} para crear un nuevo fichero ejecutable: @example $ gcc main2.es.o hola_fn.o -o hola@end example @noindent El ejecutable resultante @file{hola} ahora usa la nueva funci@'on @code{main} para producir la siguiente salida: @example $ ./hola @exclamdown{}Hola, cualquiera! @end example @noindent N@'otese que solo el fichero @file{main.es.c} ha sido recompilado y, por tanto, reenlazado con el fichero objeto existente para la funci@'on @code{hola}. Si el fichero @file{hola_fn.es.c} hubiera sido modificado, se podr@'{@dotless{i}}a haber recompilado @file{hola_fn.es.c} para crear un nuevo fichero objeto @file{hola_fn.o} y reenlazar este con el fichero @file{main.o}.@footnote{Si el prototipo de una funci@'on cambia, es necesario modificar y recompilar todos los ficheros fuentes que la usan.} En un gran proyecto con muchos ficheros fuente, recompilar solo aquellos que han sido modificados crea un significativo ahorro. El proceso de recompilar solo los ficheros modificados en un proyecto puede ser automatizado con el programa est@'andar de Unix @code{make}. @node Un peque@~no makefile @section Un peque@~no makefile @cindex makefile, ejemplo de @cindex GNU Make Para aquellos no familiarizados con @code{make}, esta secci@'on provee una demostraci@'on de su uso. @code{make} es un programa propio que puede ser encontrado en todos los sistemas Unix. Para aprender m@'as acerca de la versi@'on GNU de @code{make} se necesitar@'a consultar el manual de @cite{GNU Make} escrito por Richard M. Stallman y Roland McGrath (@pxref{Lectura adicional}). @cindex objetivo, en makefile @cindex dependencia, en makefile @cindex comando, en makefile @code{make} lee una descripci@'on de un proyecto desde un archivo conocido por @dfn{makefile} (por defecto, llamado @file{Makefile} en el directorio actual). Un makefile especifica un conjunto de reglas de compilaci@'on en t@'erminos de @dfn{objetivos} (tal como ejecutables) y sus @dfn{dependencias} (tal como ficheros objeto y ficheros fuente) en el siguiente formato: @example @i{objetivo}: @i{dependencias} @i{comando} @end example @noindent @cindex tabulador, en makefiles @cindex separador, en makefiles Por cada objetivo, make chequea el momento de modificaci@'on de los correspondientes ficheros de dependencia para determinar si el objetivo necesita ser reconstruido usando el correspondiente comando. N@'otese que las l@'{@dotless{i}}neas de @code{@i{comandos}} en un makefile deben ser indentadas con un car@'acter @key{TAB}, sin espacios. @cindex reglas impl@'{@dotless{i}}citas, en makefile @cindex reglas, en makefile @cindex @code{CFLAGS}, variable make @cindex @code{CC}, variable make @cindex @code{CXX}, variable make @cindex @code{CXXFLAGS}, variable make @cindex @code{CPPFLAGS}, variable make @cindex variables, en make GNU Make contiene muchas reglas por defecto, llamadas reglas @dfn{impl@'{@dotless{i}}citas}, para simplificar la construcci@'on de makefiles. Por ejemplo, estos especifican que ficheros @file{.o} pueden ser obtenidos desde ficheros @file{.c} al compilarse, y que un ejecutable puede ser creado enlazando ficheros @file{.o} juntos. Las reglas impl@'{@dotless{i}}citas son definidas en t@'erminos de @dfn{variables make}, tales como @code{CC} (el compilador de C) y @code{CFLAGS} (las opciones de compilaci@'on para programas C), que pueden ser asignadas usando l@'{@dotless{i}}neas @code{@i{VARIABLE}=@i{VALUE}} en el makefile. Para C++ las variables equivalentes son @code{CXX} y @code{CXXFLAGS}, mientras la variable @code{CPPFLAGS} asigna las opciones del preprocesador. Las reglas impl@'{@dotless{i}}citas y las definidas por el usuario se encadenadan juntas de forma autom@'atica como GNU Make necesite. @need 1000 Un @file{Makefile} simple para el proyecto anterior puede ser escrito como sigue: @example @verbatiminclude c1makefile2 @end example @noindent El fichero puede ser leido de la manera siguiente: usando el compilador de C @command{gcc}, con la opci@'on de compilaci@'on @option{-Wall}, se construir@'a el objetivo ejecutable @code{main} desde los ficheros objeto @file{main.o} y @file{hola_fn.o} (estos, en cambio, ser@'an construidos v@'{@dotless{i}}a reglas impl@'{@dotless{i}}citas desde @file{main.es.c} y @file{hola_fn.es.c}. El objetivo @code{clean} no tiene dependencias y simplemente elimina todos los ficheros compilados.@footnote{Esto asume que no hay ning@'un fichero llamado @file{clean} en el directorio actual ---ver la discusi@'on de `falsos objetivos' en el manual GNU Make para m@'as detalles.} La opci@'on @option{-f} (fuerza) que en el comando @command{rm} se suprima cualquier mensaje de error si los ficheros no existen. Para usar el makefile, se escribe @command{make}. Al llamarse sin argumentos, se construye el primer objetivo en el makefile, produciendo el ejecutable @file{main}. @example $ make gcc -Wall -c -o main.o main.es.c gcc -Wall -c -o hola_fn.o hola_fn.es.c gcc main.o hola_fn.o -o main $ ./main @exclamdown{}Hola, mundo! @end example @noindent Para reconstruir el ejecutable despu@'es de modificar un fichero fuente, simplemente se escribe @command{make} de nuevo. Al comprobar las fechas de modificaci@'on de los objetivos y de los ficheros dependientes, make identifica los ficheros que han cambiado y regenera los ficheros intermedios correspondientes y necesarios para actualizar los objetivos: @example $ emacs main.es.c @r{(editar el fichero)} $ make gcc -Wall -c -o main.o main.es.c gcc main.o hola_fn.o -o main $ ./main @exclamdown{}Hola, cualquiera! @end example @noindent Finalmente, para eliminar los ficheros generados, se escribe @command{make clean}: @example $ make clean rm -f main main.o hola_fn.o @end example @noindent Un makefile m@'as sofisticado normalmente contiene objetivos adicionales para instalaci@'on (@code{make install}) y testeo (@code{make check}). Los ejemplos del resto de este libro son suficientemente peque@~nos para no necesitar makefiles, pero el uso de make se recomienda en programas largos. @node Enlazando con librer@'{@dotless{i}}as externas @section Enlazando con librer@'{@dotless{i}}as externas @cindex enlazando, con librer@'{@dotless{i}}as externas @cindex librer@'{@dotless{i}}as, enlazando con @cindex @code{sqrt}, ejemplo de enlazando con @cindex C math library @cindex librer@'{@dotless{i}}a, C math library @cindex librer@'{@dotless{i}}a matem@'atica @cindex librer@'{@dotless{i}}as de sistema @cindex librer@'{@dotless{i}}as externas, enlazando con Una librer@'{@dotless{i}}a es una colecci@'on de ficheros objetos precompilados que pueden ser enlazados dentro de programas. El uso m@'as com@'un de librer@'{@dotless{i}}as es proporcionar funciones de sistema, tales como la funci@'on ra@'{@dotless{i}}z cuadrada @code{sqrt} que se encuentra en la librer@'{@dotless{i}}a matem@'atica de C. @cindex librer@'{@dotless{i}}as, almacenado en ficheros de archivo @cindex fichero de archivo, explicaci@'on de @cindex @code{.a}, extensi@'on de fichero de archivo @cindex @code{a}, extensi@'on de fichero de archivo @cindex extensi@'on del fichero, fichero de archivo @code{.a} @cindex extensi@'on, fichero de archivo @code{.a} @cindex fichero de archivo, extensi@'on @code{.a} @cindex Archivador de GNU, @code{ar} @cindex @code{ar}, GNU archiver Las librer@'{@dotless{i}}as suelen almacenarse en @dfn{ficheros de archivo} especiales con la extensi@'on @file{.a}, tambi@'en llamadas @dfn{librer@'{@dotless{i}}as est@'aticas}. @'Estas son creadas desde ficheros objeto con una herramienta propia, el archivador de GNU @code{ar}, y es usado por el enlazador para resolver referencias a funciones en tiempo de compilaci@'on. Despu@'es veremos c@'omo crear librer@'{@dotless{i}}as usando el comando @command{ar} (@pxref{Utilidades relativas al compilador}). Por simplicidad, s@'olo las librer@'{@dotless{i}}as est@'aticas se cubren en esta secci@'on ---el enlazado din@'amico en tiempo de ejecuci@'on usando @dfn{librer@'{@dotless{i}}as compartidas} ser@'a descrito en el siguiente cap@'{@dotless{i}}tulo. @cindex librer@'{@dotless{i}}as de sistemas, localizaci@'on de @cindex C standard library @cindex C library, standard @cindex standard library, C @cindex librer@'{@dotless{i}}a, C standard library El sistema de librer@'{@dotless{i}}as est@'andar normalmente se encuentra en los directorios @file{/usr/lib} y @file{/lib}.@footnote{En sistemas que soportan versiones de librer@'{@dotless{i}}as ejecutables de 32 y 64 bits, las versiones de 64 bit se almacenar@'an frecuentemente en @file{/usr/lib64} y @file{/lib64}, y las versiones de 32 bits en @file{/usr/lib} y @file{lib}.} Las librer@'{@dotless{i}}as algunas veces pueden ser encontradas en un directorio espec@'{@dotless{i}}fico de la arquitectura, como @file{/usr/lib/i386-linux-gnu/}. Por ejemplo, la librer@'{@dotless{i}}a matem@'atica de C est@'a almacenada normalmente en el fichero @file{/usr/lib/libm.a} en sistemas tipo Unix. Las declaraciones de prototipo correspondientes a las funciones de esta librer@'{@dotless{i}}a se realizan en el fichero de cabecera @file{/usr/include/math.h}. La librer@'{@dotless{i}}a est@'andar de C en s@'{@dotless{i}} misma es almacenada en @file{/usr/lib/libc.a} y contiene funciones especificadas en el est@'andar ANSI/ISO C, tal como @samp{printf} ---esta librer@'{@dotless{i}}a es enlazada por defecto en cada programa C. Aqu@'{@dotless{i}} se muestra un programa de ejemplo que realiza una llamada a la funci@'on externa @code{sqrt} en la librer@'{@dotless{i}}a matem@'atica @file{libm.a}: @example @verbatiminclude calc.es.c @end example @noindent Intentar crear un ejecutable desde este @'unico fichero fuente causa que el compilador devuelva un error en la fase de enlace: @cindex error de referencia no definida @cindex referencia, no definida debido a librer@'{@dotless{i}}a perdida @cindex librer@'{@dotless{i}}as, error de enlace debido a referencia indefinida @example @group $ gcc -Wall calc.es.c -o calc /tmp/ccbR6Ojm.o: In function `main': /tmp/ccbR6Ojm.o(.text+0x19): undefined reference to `sqrt' @end group @end example @noindent El problema es que la referencia a la funci@'on @code{sqrt} no puede ser resuelta sin la librer@'{@dotless{i}}a matem@'atica externa @file{libm.a}. La funci@'on @code{sqrt} no est@'a definida en el programa o en la librer@'{@dotless{i}}a por defecto @file{libc.a}, y el compilador no enlaza al fichero @file{libm.a} a menos que @'este est@'e expl@'{@dotless{i}}citamente seleccionado. @cindex directorio @file{/tmp}, ficheros temporales @cindex ficheros temporales, escritos en @file{/tmp} @cindex ficheros objeto, temporal Casualmente, el fichero mencionado el mensaje de error @file{/tmp/ccbR60jm.o} es un fichero objeto temporal creado por el compilador desde @file{calc.es.c}, para llevar a cabo el proceso de enlace. Para permitir que el compilador enlace la funci@'on @code{sqrt} al programa main de @file{calc.es.c} es necesario proveer la librer@'{@dotless{i}}a @file{libm.a}. Un obvio pero no convencional modo de hacer esto es especificarlo de manera expl@'{@dotless{i}}cita en la l@'{@dotless{i}}nea de comandos: @example $ gcc -Wall calc.es.c /usr/lib/libm.a -o calc @end example @noindent La librer@'{@dotless{i}}a @file{libm.a} contiene los ficheros objeto para todas las funciones matem@'aticas, tales como @code{sin}, @code{cos}, @code{exp}, @code{log} y @code{sqrt}. El enlazador busca a trav@'es de estos para encontrar el fichero objeto conteniendo la funci@'on @code{sqrt}. Una vez que el fichero objeto para la funci@'on @code{sqrt} fu@'e encontrado, el programa main puede ser enlazado y se produce un ejecutable completo: @example $ ./calc La ra@'{@dotless{i}}z cuadrada de 2.000000 es 1.414214 @end example @noindent El fichero ejecutable incluye el c@'odigo m@'aquina para la funci@'on main y el c@'odigo m@'aquina para la funci@'on @code{sqrt}, copiado desde el archivo objeto correspondiente en la librer@'{@dotless{i}}a @file{libm.a}. @cindex enlazando, con librer@'{@dotless{i}}a usando @option{-l} @cindex librer@'{@dotless{i}}as, enlazando con @cindex @option{-l}, opci@'on para enlazar con librer@'{@dotless{i}}as @cindex @option{-lm}, opci@'on de enlace con librer@'{@dotless{i}}a matem@'atica @cindex @option{l}, opci@'on para enlazar con librer@'{@dotless{i}}as @cindex librer@'{@dotless{i}}a matem@'atica, enlazando con @option{-lm} Para evitar la necesidad de especificar largas rutas en la l@'{@dotless{i}}nea de comandos, el compilador proporciona una opci@'on de atajo @samp{-l} para enlazar librer@'{@dotless{i}}as. Por ejemplo, el siguiente comando, @example $ gcc -Wall calc.es.c -lm -o calc @end example @noindent es equivalente al comando original usando el nombre de la librer@'{@dotless{i}}a completa @file{/usr/lib/libm.a}. En general, la opci@'on del compilador @option{-l@var{NAME}} intentar@'a enlazar ficheros objeto con un fichero de librer@'{@dotless{i}}a @file{lib@var{NAME}.a} en los directorios de librer@'{@dotless{i}}a est@'andar. Los directorios adicionales pueden especificarse con opciones de la l@'{@dotless{i}}nea comandos y variables de entorno, por decirlo resumidamente. Un programa largo normalmente usar@'a muchas opciones @option{-l} para enlazar a librer@'{@dotless{i}}as tales como la librer@'{@dotless{i}}a matem@'atica, librer@'{@dotless{i}}as gr@'aficas y librer@'{@dotless{i}}as de red. @menu * Orden de enlace de librer@'{@dotless{i}}as:: @end menu @node Orden de enlace de librer@'{@dotless{i}}as @subsection Orden de enlace de librer@'{@dotless{i}}as @cindex librer@'{@dotless{i}}as, orden de enlace @cindex orden de enlace, de librer@'{@dotless{i}}as @cindex orden de enlace, de izquierda a derecha El comportamiento tradicional de los enlazadores es buscar funciones externas de izquierda a derecha en las librer@'{@dotless{i}}as especificadas en la l@'{@dotless{i}}nea de comandos. Esto significa que una librer@'{@dotless{i}}a que contiene la definici@'on de una funci@'on deber@'{@dotless{i}}a aparecer despu@'es de cualquier fichero fuente o ficheros objeto que la usen. Esto incluye librer@'{@dotless{i}}as especificadas con la opci@'on @option{-l}, como se muestra en el siguiente comando: @example $ gcc -Wall calc.es.c -lm -o calc @r{(orden correcto)} @end example @noindent Con algunos enlazadores el orden opuesto (poner la opci@'on @option{-lm} antes del fichero que lo usa) dar@'{@dotless{i}}a como resultado un error, @example $ cc -Wall -lm calc.es.c -o calc @r{(orden incorrecto)} main.o: In function `main': main.o(.text+0xf): undefined reference to `sqrt' @end example @noindent @cindex error de referencia no definida @cindex error, referencia indefinida debido al orden de enlace de librer@'{@dotless{i}}as @cindex enlazado, error de referencia indefinida debido al orden de enlace de librer@'{@dotless{i}}as debido a que no hay librer@'{@dotless{i}}a o fichero objeto que contenga @code{sqrt} despu@'es de @file{calc.es.c}. La opci@'on @option{-lm} deber@'{@dotless{i}}a aparecer despu@'es del fichero @file{calc.es.c}. Cuando se usan varias librer@'{@dotless{i}}as, se deber@'{@dotless{i}}a usar la misma convenci@'on que con las librer@'{@dotless{i}}as en s@'{@dotless{i}}. Una librer@'{@dotless{i}}a que llama a una funci@'on externa definida en otra librer@'{@dotless{i}}a deber@'{@dotless{i}}a aparecer antes que la librer@'{@dotless{i}}a que contiene la funci@'on. @cindex ordenando librer@'{@dotless{i}}as @cindex librer@'{@dotless{i}}as, orden de enlace Por ejemplo, un programa @file{data.es.c} usando la librer@'{@dotless{i}}a GNU Linear Programming library @file{libglpk.a}, que a su vez usa la librer@'{@dotless{i}}a matem@'atica @file{libm.a}, se compila as@'{@dotless{i}}: @example $ gcc -Wall data.es.c -lglpk -lm @end example @noindent debido a que los fichero objetos de @file{libglpk.a} usan funciones definidas en @file{libm.a}. @c With some compilers the opposite ordering would result in @c an error, @c @c @example @c $ cc -Wall data.c -lm -lglpk @r{(incorrect order)} @c main.o: In function `main': @c main.o(.text+0xf): undefined reference to `exp' @c @end example @c @noindent @c because there is no library containing mathematical functions used by @c @file{libglpk.a} (such as @code{exp}) after the @option{-lglpk} option. La mayor@'{@dotless{i}}a de los enlazadores actuales buscar@'an todas las librer@'{@dotless{i}}as, sin importar el orden, pero debido a que algunos no hacen esto es mejor seguir la convenci@'on de ordenar las librer@'{@dotless{i}}as de izquierda a derecha. Es @'util tener todo esto en mente si se encuentran problemas inesperados con referencias no definidas, y mirar si todas las librer@'{@dotless{i}}as necesarias aparecen en la l@'{@dotless{i}}nea de comandos. @node Usando librer@'{@dotless{i}}as de archivos de cabeceras @section Usando librer@'{@dotless{i}}as de archivos de cabeceras @cindex fichero de cabecera, perdido @cindex declaraci@'on, perdida @cindex ficheros de cabecera perdidos @cindex librer@'{@dotless{i}}a de ficheros de cabecera, usando Cuando se usa una librer@'{@dotless{i}}a es esencial incluir los ficheros de cabecera apropiados, para as@'{@dotless{i}} declarar los argumentos de funciones y devolver valores con los tipos correctos. Sin declaraciones, los argumentos de una funci@'on pueden pasar el tipo err@'oneo, causando resultados corruptos. El siguiente ejemplo muestra otro programa que crea una llamada de funci@'on para la librer@'{@dotless{i}}a est@'andar de C. En este caso, la funci@'on @code{strtod} es usada para convertir una cadena @code{\"123\"} a un n@'umero en coma flotante: @example @verbatiminclude badconv.es.c @end example @noindent Sin embargo, el programa contiene un error ---la sentencia @code{#include} para la necesaria cabecera @file{stdlib.h} no se encuentra, as@'{@dotless{i}} el prototipo @code{double strtod (const char * string, char * tail)} no ser@'a visto por el compilador. @c Note that in this case the format specifier @c @code{%f} is correct, since @code{x} is a floating point variable. @c @cindex @code{math.h}, header file for mathematical functions La compilaci@'on del programa sin opciones de aviso producir@'a un fichero ejecutable que da resultados incorrectos: @cindex error, ejemplo de @example $ gcc badconv.es.c -lm $ ./a.out El valor es 966656.000000 @r{(resultado incorrecto, deber@'{@dotless{i}}a ser 123.0)} @end example @noindent @cindex C/C++, riesgos de uso Los resultados est@'an corruptos porque los argumento y el valor devuelto de la llamada a @code{strtod} son pasados con tipos incorrectos.@footnote{La actual salida anterior puede diferir, dependiendo de la plataforma y el entorno espec@'{@dotless{i}}ficos.} Esto puede ser detectado activando la opci@'on de avisos @option{-Wall}: @example $ gcc -Wall badconv.es.c -lm badconv.es.c: In function `main': badconv.es.c:6: warning: implicit declaration of function `strtod' @end example @noindent @cindex declaraci@'on impl@'{@dotless{i}}cita de funci@'on @cindex fichero de cabecera, la cabecera perdida causa declaraci@'on impl@'{@dotless{i}}cita @cindex fichero de cabecera perdida, causa declaraci@'on impl@'{@dotless{i}}cita @c The error is now detected and can be fixed by adding the line @c @code{#include } to the beginning of the source file. Este ejemplo muestra de nuevo la importancia de usar la opci@'on de aviso @option{-Wall} para detectar problemas serios que de otro modo no podr@'{@dotless{i}}an ser f@'acilmente localizados. @node Opciones de compilaci@'on @chapter Opciones de compilaci@'on @cindex compilaci@'on, opciones @cindex opciones, compilaci@'on Este cap@'{@dotless{i}}tulo describe otras opciones del compilador com@'unmente usadas disponibles en GCC. Estas opciones controlan funcionalidades tales como buscar rutas usadas para localizar librer@'{@dotless{i}}as e incluir ficheros, el uso de avisos adicionales y diagn@'osticos, macros del preprocesador y dialectos del lenguaje C. @menu * Asignando rutas de b@'usqueda:: * Librer@'{@dotless{i}}as compartidas y librer@'{@dotless{i}}as est@'aticas:: * Est@'andares del lenguaje C:: * Opciones de aviso en -Wall:: * Opciones de aviso adicionales:: * Opciones de aviso recomendadas:: @end menu @node Asignando rutas de b@'usqueda @section Asignando rutas de b@'usqueda @cindex rutas de b@'usqueda @cindex rutas, b@'usqueda En el @'ultimo cap@'{@dotless{i}}tulo, se vi@'o c@'omo enlazar a un programa con funciones de la librer@'{@dotless{i}}a matem@'atica @file{libm.a}, usando la opci@'on de atajo @option{-lm} y el fichero de cabecera @file{math.h}. Un problema com@'un cuando se compila un programa usando ficheros de cabecera es el error: @cindex No such file or directory, header file not found @cindex fichero de cabecera, no encontrado @example @var{FILE.h}: No such file or directory @end example @noindent Esto ocurre si un fichero de cabecera no est@'a presente en los directorios de ficheros include est@'andar usados por @code{gcc}. Un problema similar puede ocurrir en librer@'{@dotless{i}}as: @cindex cannot find @var{library} error @cindex error de enlace, no se puede encontrar librer@'{@dotless{i}}a @example /usr/bin/ld: cannot find @var{library} @end example @noindent Esto ocurre si una librer@'{@dotless{i}}a usada para enlazar no est@'a presente en los directorios de librer@'{@dotless{i}}a est@'andar usados por @code{gcc}. Por defecto, @code{gcc} busca en los siguientes directorios los ficheros de cabecera: @cindex ld: cannot find library error @cindex error de enlace, no se puede encontrar librer@'{@dotless{i}}a @cindex directorios por defecto, enlazando y ficheros de cabecera @cindex enlazando, directorios por defecto @cindex fichero de cabecera, directorios por defecto @example /usr/local/include/ /usr/include/ @end example @noindent y los siguientes directorios para librer@'{@dotless{i}}as: @example /usr/local/lib/ /usr/lib/ @end example @noindent La lista de directorios para ficheros de cabecera son referidos con frecuencia como @dfn{ruta de include}, y la lista de directorios para librer@'{@dotless{i}}as como @dfn{ruta de b@'usqueda de librer@'{@dotless{i}}as} o @dfn{ruta de enlace}. @cindex librer@'{@dotless{i}}as, en plataformas de 64 bits @cindex plataformas de 64 bits, directorios de librer@'{@dotless{i}}a adicionales @cindex librer@'{@dotless{i}}as de sistemas, localizaci@'on de Los directorios en estas rutas son buscados en orden, desde el primero hasta el @'ultimo en los dos listados de arriba.@footnote{Las rutas de b@'usqueda por defecto pueden tambi@'en incluir directorios adicionales y dependientes del sistema o espec@'{@dotless{i}}ficos del sitio, y directorios en la instalaci@'on de GCC en s@'{@dotless{i}}. Por ejemplo, en plataformas de 64 bits directorios adicionales @file{lib64} pueden tambi@'en ser b@'uscados por defecto.} Por ejemplo, un fichero de cabecera encontrado en @file{/usr/local/include} precede a un fichero con el mismo nombre en @file{/usr/include}. De manera similar, una librer@'{@dotless{i}}a encontrada en @file{/usr/local/lib} preceder@'a a una librer@'{@dotless{i}}a con el mismo nombre en @file{/usr/lib}. @cindex @option{-L}, opci@'on de ruta de b@'usqueda de librer@'{@dotless{i}}a @cindex @option{L}, opci@'on de ruta de b@'usqueda de librer@'{@dotless{i}} @cindex @option{-I}, opci@'on para asignar la ruta de include @cindex @option{I}, opci@'on para asignar la ruta de include @cindex librer@'{@dotless{i}}as, extendiendo ruta de b@'usqueda con @option{-L} @cindex ruta de include, extendiendo con @option{-I} @cindex fichero de cabecera, ruta de include ---extendiendo con @option{-I} Cuando se instalan librer@'{@dotless{i}}as adicionales en otros directorios es necesario extender las rutas de b@'usqueda, para que las librer@'{@dotless{i}}as sean encontradas. Las opciones del compilador @option{-I} y @option{-L} a@~naden nuevos directorios al principio de la ruta include y la ruta de b@'usqueda de librer@'{@dotless{i}}a respectivamente. @menu * Ejemplo de ruta de b@'usqueda:: * Variables de entorno:: * Rutas de b@'usqueda extendidas:: @end menu @node Ejemplo de ruta de b@'usqueda @subsection Ejemplo de ruta de b@'usqueda @cindex rutas de b@'usqueda, ejemplo @cindex @code{gdbm}, GNU DBM library @cindex pares clave valor, almacenados con GDBM @cindex fichero DBM, creado con @code{gdbm} El siguiente programa de ejemplo usa una librer@'{@dotless{i}}a que podr@'{@dotless{i}}a ser instalada como un paquete adicional en un sistema ---la GNU Database Management Library (GDBM). La librer@'{@dotless{i}}a GDBM almacena pares clave:valor en un fichero DBM, un tipo de fichero de datos que permite que los valores sean almacenados e indexados por una @dfn{clave} (una arbitraria secuencia de caracteres). Aqu@'{@dotless{i}} est@'a el programa de ejemplo @file{dbmain.es.c}, que crea un fichero DBM conteniendo una clave @samp{clavetest} con el valor @samp{valortest}: @example @verbatiminclude dbmain.es.c @end example @noindent El programa usa el fichero de cabecera @file{gdbm.h} y la librer@'{@dotless{i}}a @file{libgdbm.a}. Si la librer@'{@dotless{i}}a ha sido instalada en la localizaci@'on por defecto @file{/usr/local/lib}, con el fichero de cabecera en @file{/usr/local/include}, entonces el programa puede ser compilado con el siguiente comando: @example $ gcc -Wall dbmain.es.c -lgdbm @end example @noindent Ambos de estos directorios son parte del @code{gcc} por defecto e incluyen enlaces y rutas. Sin embargo, si GDBM ha sido instalado en una localizaci@'on diferente, al intentar compilar el programa se obtendr@'a el siguiente error: @cindex No such file or directory, header file not found @example $ gcc -Wall dbmain.es.c -lgdbm dbmain.es.c:1: gdbm.h: No such file or directory @end example @noindent Por ejemplo, si la versi@'on 1.8.3 del paquete GDBM est@'a instalada en el directorio @file{/opt/gdbm-1.8.3} la localizaci@'on del fichero de cabecera ser@'{@dotless{i}}a, @example /opt/gdbm-1.8.3/include/gdbm.h @end example @noindent que no es parte de la ruta include del @code{gcc} por defecto. A@~nadiendo el directorio apropiado para la ruta include con la opci@'on @option{-I} en l@'{@dotless{i}}nea de comandos, permite que el programa se compile, pero no se enlace: @cindex cannot find @var{library} error @example $ gcc -Wall -I/opt/gdbm-1.8.3/include dbmain.es.c -lgdbm /usr/bin/ld: cannot find -lgdbm collect2: ld returned 1 exit status @end example @noindent @c The location of the library itself would be, @c @example @c /opt/gdbm-1.8.3/lib/libgdbm.a @c @end example @c @noindent El directorio que contiene la librer@'{@dotless{i}}a no est@'a incluido en la ruta de enlace. @'Este puede ser a@~nadido a la ruta de enlace usando la siguiente opci@'on: @example -L/opt/gdbm-1.8.3/lib/ @end example @noindent El siguiente comando permite que el programa sea compilado y enlazado: @example $ gcc -Wall -I/opt/gdbm-1.8.3/include -L/opt/gdbm-1.8.3/lib dbmain.es.c -lgdbm @end example @noindent Esto produce el ejecutable final enlazado a la librer@'{@dotless{i}}a GDBM. Antes de ver como funciona este ejecutable se dar@'a una breve mirada a las variables de entorno que afecta a las opciones @option{-I} y @option{-L}. N@'otese que nunca se localizar@'an las rutas absolutas de los ficheros de cabecera en sentencias @code{#include} en el c@'odigo fuente, ya que esto evitar@'{@dotless{i}}a que el programa se compilase en otros sistemas. La opci@'on @option{-I} o la variable @env{INCLUDE_PATH} descrita anteriormente siempre se deber@'{@dotless{i}}a usar para asignar la ruta include para los ficheros de cabecera. @node Variables de entorno @subsection Variables de entorno @cindex variables de entorno, por defecto rutas de b@'usqueda @cindex variables de shell La b@'usqueda de rutas para los ficheros de cabecera y librer@'{@dotless{i}}as puede tambi@'en ser controlado a trav@'es de las variables de entorno en la shell. Estas pueden ser asignadas de manera autom@'atica por cada sesi@'on usando el apropiado fichero de acceso, tal como @file{.bash_profile} en el caso de GNU Bash. @cindex fichero @code{bash} profile, configuraciones de login @cindex ruta include, asignaci@'on con variables de entorno @cindex ruta include de C @cindex ruta include de C++ @cindex @env{C_INCLUDE_PATH} @cindex @env{CPLUS_INCLUDE_PATH} Los directorios adicionales pueden ser a@~nadidos para la ruta include usando la variable de entorno @env{C_INCLUDE_PATH} (para ficheros de cabecera de C). Por ejemplo, los siguientes comandos a@~nadir@'an @file{/opt/gdbm-1.8.3/include} a la ruta include cuando se compilan programas C: @example $ C_INCLUDE_PATH=/opt/gdbm-1.8.3/include $ export C_INCLUDE_PATH @end example @noindent y de manera similar para programas C++: @example $ CPLUS_INCLUDE_PATH=/opt/gdbm-1.8.3/include $ export CPLUS_INCLUDE_PATH @end example @noindent Este directorio ser@'a buscado despu@'es de cualquier directorio especificado en el comando con la opci@'on @option{-I}, y antes de los directorios est@'andar por defecto (tales como @file{/usr/local/include} y @file{/usr/include}). El comando de shell @code{export} es necesario para crear la variable de entorno disponible a programas fuera de la shell en s@'{@dotless{i}}, tales como el compilador ---es solo necesario unavez por cada variable en cada sesi@'on de shell, y tambi@'en puede ser asignado en el apropiado fichero de login.@footnote{En GNU Bash, la forma corta @code{export @var{VARIABLE}=@var{VALOR}} tambi@'en se permite.} De manera similar, directorios adicionales pueden ser a@~nadidos a la ruta de enlace usando la variable de entorno @env{LIBRARY_PATH}. Por ejemplo, los siguientes comandos a@~nadir@'an @file{/opt/gdbm-1.8.3/lib} a la ruta de enlace. @cindex ruta de enlace, asignaci@'on con variable de entorno @example $ LIBRARY_PATH=/opt/gdbm-1.8.3/lib $ export LIBRARY_PATH @end example @noindent Este directorio ser@'a buscado despu@'es de que cualquier directorio especificado en la l@'{@dotless{i}}nea de comandos con la opci@'on @option{-L}, y antes que los directorios est@'andar por defecto (tales como @file{/usr/local/lib} y @file{/usr/lib}). Con las configuraciones de las variables de entorno dadas arriba el programa @file{dbmain.es.c} puede ser compilado sin las opciones @option{-I} y @option{-L}, @example $ gcc -Wall dbmain.es.c -lgdbm @end example @noindent porque la rutas por defecto ahora usan los directorios especificados en las variables de entorno @env{C_INCLUDE_PATH} y @env{LIBRARY_PATH}. El mismo comando de compilaci@'on con @code{g++} deber@'{@dotless{i}}a usar las variables de entorno @env{CPLUS_INCLUDE_PATH} y @env{LIBRARY_PATH}. @c Note @c that these defaults are in addition to the system directories @c @file{/usr/include}, @file{/usr/lib}, @file{/usr/local/include} and @c @file{/usr/local/lib} which are always searched. @node Rutas de b@'usqueda extendidas @subsection Rutas de b@'usqueda extendidas @cindex m@'ultiples directorios, al incluir y rutas de enlace @cindex rutas de b@'usqueda extendida, para incluir y directorios de enlace @cindex rutas de b@'usqueda, extendida Siguiendo la convenci@'on est@'andar de Unix para la b@'usqueda de rutas, varios directorios pueden ser especificados en una variable de entorno como una lista cuyos elementos se separan con el car@'acter dos puntos `:': @example @var{DIR1}:@var{DIR2}:@var{DIR3}:... @end example @noindent Los directorios son buscados de izquierda a derecha. Un punto simple @samp{.} puede ser usado para especificar el directorio actual.@footnote{El directorio actual tambi@'en puede ser especificado usando una ruta vac@'{@dotless{i}}a. Por ejemplo, @code{:@var{DIR1}:@var{DIR2}} es equivalente a @code{.:@var{DIR1}:@var{DIR2}}.} Por ejemplo, la siguiente configuraci@'on crea un include por defecto y enlaza rutas para paquetes instalados en el directorio actual @file{.} y en los directorios @file{include} y @file{lib} bajo @file{/opt/gdbm-1.8.3} y @file{/net} respectivamente: @example $ C_INCLUDE_PATH=.:/opt/gdbm-1.8.3/include:/net/include $ LIBRARY_PATH=.:/opt/gdbm-1.8.3/lib:/net/lib @end example @noindent Para programas C++, se usa la variable de entorno @env{CPLUS_INCLUDE_PATH} en vez de @env{C_INCLUDE_PATH}. Para especificar m@'ultiples rutas de b@'usqueda en la l@'{@dotless{i}}nea de comandos, las opciones @option{-I} y @option{-L} pueden ser repetidas. Por ejemplo, el siguiente comando, @example $ gcc -I. -I/opt/gdbm-1.8.3/include -I/net/include -L. -L/opt/gdbm-1.8.3/lib -L/net/lib ..... @end example @noindent es equivalente a las configuraciones en la variable de entornos dadas anteriormente. Cuando las variables de entorno y las opciones de comandos son usados juntos el compilador busca los directorios en el siguiente orden: @enumerate @item opciones de comandos @option{-I} y @option{-L}, de izquierda a derecha @item directorios especificados por variables de entornos, tales como @env{C_INCLUDE_PATH} (para programas C), @env{CPLUS_INCLUDE_PATH} (para programas C++) y @env{LIBRARY_PATH} @item directorios de sistema por defecto @end enumerate @noindent En el uso del d@'{@dotless{i}}a a d@'{@dotless{i}}a, los directorios son normalmente a@~nadidos a rutas de b@'usqueda con las opciones @option{-I} y @option{-L}. @node Librer@'{@dotless{i}}as compartidas y librer@'{@dotless{i}}as est@'aticas @section Librer@'{@dotless{i}}as compartidas y librer@'{@dotless{i}}as est@'aticas @cindex librer@'{@dotless{i}}as compartidas @cindex librer@'{@dotless{i}}as est@'aticas Aunque el programa de ejemplo de arriba ha sido exitosamente compilado y enlazado, es necesario un paso final antes de ser capaz de cargar y ejecutar el fichero ejecutable. En un intento por iniciar la ejecuci@'on directamente, suceder@'a el siguiente error en la mayor@'{@dotless{i}}a de los sistemas: @cindex error while loading shared libraries @cindex cannot open shared object file @cindex librer@'{@dotless{i}}as compartidas, error al cargarse @cindex librer@'{@dotless{i}}as, error al cargar librer@'{@dotless{i}}a compartida @example $ ./a.out ./a.out: error while loading shared libraries: libgdbm.so.3: cannot open shared object file: No such file or directory @end example @noindent Esto es porque el paquete GDBM proporciona una @dfn{librer@'{@dotless{i}}a compartida}. Este tipo de librer@'{@dotless{i}}a requiere un tratamiento especial ---debe ser cargada desde disco antes de que el ejecutable cargue. Las librer@'{@dotless{i}}as externas se proveen normalmente de dos formas: @dfn{librer@'{@dotless{i}}as est@'aticas} y @dfn{librer@'{@dotless{i}}as compartidas}. Las librer@'{@dotless{i}}as est@'aticas son los ficheros @file{.a} vistos antes. Cuando un programa es enlazado a una librer@'{@dotless{i}}a est@'atica, el c@'odigo m@'aquina de los ficheros objetos para cualquier funci@'on externa usada por el programa es copiado desde la librer@'{@dotless{i}}a al ejecutable final. @cindex @code{.so}, extensi@'on de fichero objeto compartido @cindex @code{so}, extensi@'on de fichero objeto compartido @cindex extensi@'on, fichero objeto compartido @code{.so} @cindex extensi@'on de fichero, fichero objeto compartido @code{.so} @cindex fichero objeto compartido, extensi@'on @code{.so} @cindex librer@'{@dotless{i}}a din@'amicamente enlazada, ver librer@'{@dotless{i}}as compartidas @cindex DLL (dynamically linked library), ver librer@'{@dotless{i}}as compartidas Las librer@'{@dotless{i}}as compartidas son manejadas con una forma m@'as avanzada de enlace, que crea el fichero ejecutable m@'as peque@~no. Ellas usan la extensi@'on @file{.so}, soportado por los @dfn{objetos compartidos}. @cindex funci@'on de carga @cindex carga din@'amica @cindex enlazando, din@'amicamente (librer@'{@dotless{i}}as compartidas) Un fichero ejecutable enlazado a una librer@'{@dotless{i}}a compartida contiene solo una peque@~na parte de las funciones requeridas, en vez del c@'odigo m@'aquina completo de los ficheros para las funciones externas. Antes de que el fichero ejecutable empiece su ejecuci@'on, el c@'odigo m@'aquina de las funciones externas es copiado en memoria desde el fichero de la librer@'{@dotless{i}}a compartida por el sistema operativo ---un proceso referido como @dfn{enlace din@'amico}. @cindex librer@'{@dotless{i}}as compartidas, ventajas de @cindex espacio en disco, uso reducido por librer@'{@dotless{i}}as compartidas El enlace din@'amico crea ficheros ejecutables peque@~nos y reserva espacio en disco, porque una copia de una librer@'{@dotless{i}}a puede ser compartida entre m@'ultiples programas. En la mayor@'{@dotless{i}}a de los sistemas operativos tambi@'en se proporciona un mecanismo de memoria virtual que permite que una copia de una librer@'{@dotless{i}}a compartida en memoria f@'{@dotless{i}}sica sea usada por todos los programas en ejecuci@'on, ahorrando tanto memoria como espacio en disco. Adem@'as, las librer@'{@dotless{i}}as compartidas hacen posible actualizar una librer@'{@dotless{i}}a sin recompilar los programas que ella usa (la interfaz dada a la librer@'{@dotless{i}}a no cambia). Por estas ventajas @code{gcc} compila programas para usar librer@'{@dotless{i}}as compartidas por defecto en la mayor@'{@dotless{i}}a de los sistemas, si @'estas est@'an disponibles. Siempre y cuando una librer@'{@dotless{i}}a est@'atica @file{lib@var{NAME}.a} sea usada para enlazarse con la opci@'on @option{-l@var{NAME}} el compilador primero busca una librer@'{@dotless{i}}a compartida alternativa con el mismo nombre y una extensi@'on @file{.so}. En este caso, cuando el compilador busca la librer@'{@dotless{i}}a @file{libgdbm} en la ruta de enlace, @'este encuentra los dos ficheros siguientes en el directorio @file{/opt/gdbm-1.8.3/lib}: @example $ cd /opt/gdbm-1.8.3/lib $ ls libgdbm.* libgdbm.a libgdbm.so @end example @noindent Por consiguiente, el fichero del objeto compartido @file{libgdbm.so} es usado de manera preferente a la librer@'{@dotless{i}}a est@'atica @file{libgdbm.a}. @cindex @option{-rpath}, opci@'on para asignar ruta de b@'usqueda de librer@'{@dotless{i}}a compartida en tiempo de ejecuci@'on @cindex @option{rpath}, opci@'on para asignar ruta de b@'usqueda de librer@'{@dotless{i}}a compartida en tiempo de ejecuci@'on Sin embargo, cuando el fichero ejecutable es iniciado su funci@'on de carga, debe encontrar la librer@'{@dotless{i}}a compartida para cargarlo en memoria. Por defecto el cargador busca librer@'{@dotless{i}}as compartidas s@'olo en un conjunto predefinido de directorios de sistema tales como @file{/usr/local/lib} y @file{/usr/lib}. Si la librer@'{@dotless{i}}a no est@'a localizada en uno de estos directorios debe ser a@~nadida a la ruta de carga.@footnote{N@'otese que el directorio que contiene la librer@'{@dotless{i}}a compartida puede, en principio, ser guardado (``hard-coded'') en el propio ejecutable usando la opci@'on del enlazador @option{-rpath}, pero esto no es hecho normalmente debido a que da problemas si la librer@'{@dotless{i}}a se ha movido o el ejecutable est@'a copiado a otro sistema.} @cindex @env{LD_LIBRARY_PATH}, ruta de carga de librer@'{@dotless{i}}a compartida @cindex librer@'{@dotless{i}}as compartidas, asignando ruta de carga @cindex variables de entorno @cindex variables de shell El camino m@'as simple para definir la ruta de carga es a trav@'es de la variable de entorno @env{LD_LIBRARY_PATH}. Por ejemplo, los comandos siguientes definen la ruta de carga a @file{/opt/gdbm-1.8.3/lib} y as@'{@dotless{i}} el fichero @file{libgdbm.so} puede ser encontrado: @example $ LD_LIBRARY_PATH=/opt/gdbm-1.8.3/lib $ export LD_LIBRARY_PATH $ ./a.out Almacenado el par clave-valor... hecho. @end example @noindent El ejecutable ahora funciona bien, imprime su mensaje y crea un fichero DBM llamado @file{test} conteniendo el par clave:valor @samp{clavetest} y @samp{valortest}. @cindex variables de entorno, asignaci@'on permanente @cindex variables shell, asignaci@'on permanente @cindex fichero de login, asignando variables de entorno en @'el @cindex fichero profile, asignando variables de entorno en @'el Para ahorrar escritura, la variable de entorno @env{LD_LIBRARY_PATH} puede ser definida de forma autom@'atica por cada sesi@'on usando el apropiado fichero de login, tal como @file{.bash_profile} para la shell GNU Bash. @cindex fichero @code{bash} profile, configuraciones de login Varios directorios de librer@'{@dotless{i}}as compartidas pueden ser fijadas en la ruta de carga, como una lista separada por dos puntos @code{@var{DIR1}:@var{DIR2}:@var{DIR3}:...:@var{DIRN}}. Por ejemplo, el siguiente comando define la ruta de carga para usar los directorios @file{lib} bajo @file{/opt/gdbm-1.8.3} y @file{/opt/gtk-1.4}: @cindex variables de entorno, extendiendo una ruta existente @cindex rutas, extendiendo la variable de entorno @example $ LD_LIBRARY_PATH=/opt/gdbm-1.8.3/lib:/opt/gtk-1.4/lib $ export LD_LIBRARY_PATH @end example @noindent Si la ruta de carga contiene entradas existentes, puede ser extendida usando la sintaxis @code{LD_LIBRARY_PATH=@var{NEWDIRS}:$LD_LIBRARY_PATH}. Por ejemplo, el siguiente comando a@~nade el directorio @file{/opt/gsl-1.5/lib} a la ruta mostrada arriba: @example $ LD_LIBRARY_PATH=/opt/gsl-1.5/lib:$LD_LIBRARY_PATH $ echo $LD_LIBRARY_PATH /opt/gsl-1.5/lib:/opt/gdbm-1.8.3/lib:/opt/gtk-1.4/lib @end example @noindent Para el administrador de sistemas es posible definir la variables @env{LD_LIBRARY_PATH} para todos los usuarios, a@~nadi@'endola al script de login por defecto, normalmente @file{/etc/profile}. En sistemas GNU, una ruta de sistema puede ser tambi@'en definida en el fichero de configuraci@'on del cargador @file{/etc/ld.so.conf}. @cindex fichero de configuraci@'on del cargador, @code{ld.so.conf} @cindex @code{ld.so.conf}, fichero de configuraci@'on del cargador @cindex @option{-static}, opci@'on que fuerza el enlace est@'atico @cindex @option{static}, opci@'on que fuerza el enlace est@'atico @cindex enlazando est@'aticamente, se fuerza con @option{-static} De manera alternativa, el enlace est@'atico puede ser forzado con la opci@'on @option{-static} de @code{gcc} para evitar el uso de librer@'{@dotless{i}}as compartidas: @example $ gcc -Wall -static -I/opt/gdbm-1.8.3/include/ -L/opt/gdbm-1.8.3/lib/ dbmain.es.c -lgdbm @end example @noindent Esto crea un ejecutable enlazado con la librer@'{@dotless{i}}a est@'atica @file{libgdbm.a} que puede ser ejecutada sin asignar la variable de entorno @env{LD_LIBRARY_PATH} o poniendo librer@'{@dotless{i}}as compartidas en los directorios por defecto: @example $ ./a.out Almacenando el par clave-valor... hecho. @end example @noindent Como ya se coment@'o, tambi@'en es posible enlazar directamente con librer@'{@dotless{i}}as de ficheros individuales especificando la ruta completa a la librer@'{@dotless{i}}a en la l@'{@dotless{i}}nea de comandos. Por ejemplo, el siguiente comando enlazar@'a directamente con la librer@'{@dotless{i}}a est@'atica @file{libgdbm.a}, @example $ gcc -Wall -I/opt/gdbm-1.8.3/include dbmain.es.c /opt/gdbm-1.8.3/lib/libgdbm.a @end example @noindent y el comando de abajo enlazar@'a con el fichero de librer@'{@dotless{i}}a compartida @file{libgdbm.so}: @example $ gcc -Wall -I/opt/gdbm-1.8.3/include dbmain.es.c /opt/gdbm-1.8.3/lib/libgdbm.so @end example @noindent En el @'ultimo caso a@'un es necesario definir la ruta de carga de librer@'{@dotless{i}}a cuando se ejecuta el ejecutable. @node Est@'andares del lenguaje C @section Est@'andares del lenguaje C @cindex lenguaje C, dialectos de @cindex dialectos del lenguaje C @cindex ANSI/ISO C, comparado con extensiones GNU C @cindex ISO C, comparado con extensiones GNU C @cindex extensiones GNU C, comparadas con ANSI/ISO C @cindex @option{-ansi}, opci@'on que inhabilita extensiones del lenguaje @cindex @option{ansi}, opci@'on que inhabilita extensiones del lenguaje @cindex @option{-pedantic}, opci@'on conforme al est@'andar ANSI (con @option{-ansi}) @cindex @option{pedantic}, opci@'on @cindex @option{-std}, opci@'on que selecciona un est@'andar espec@'{@dotless{i}}fico del lenguaje @cindex @option{std}, opci@'on que selecciona un est@'andar espec@'{@dotless{i}}fico del lenguaje Por defecto, @code{gcc} compila programas usando el dialecto GNU del lenguaje C, llamado como @dfn{GNU C}. Este dialecto incorpora el est@'andar oficial ANSI/ISO para el lenguaje C con varias extensiones @'utiles de GNU, tales como funciones anidadas y vectores de tama@~no variable. La mayor@'{@dotless{i}}a de los programas ANSI/ISO compilar@'an bajo GNU C sin cambios. Hay varias opciones que controlan el dialecto de C usado por @code{gcc}. Las opciones m@'as com@'unmente usadas son @option{-ansi} y @option{-pedantic}. Los dialectos espec@'{@dotless{i}}ficos del lenguaje C por cada est@'andar pueden tambi@'en ser seleccionadas con la opci@'on @option{-std}. @menu * ANSI/ISO:: * ANSI/ISO estricto:: * Seleccionando est@'andares espec@'{@dotless{i}}ficos:: @end menu @node ANSI/ISO @subsection ANSI/ISO @cindex ANSI/ISO C, controlado con la opci@'on @option{-ansi} @cindex ISO C, controlado con la opci@'on @option{-ansi} A veces un programa ANSI/ISO puede ser incompatible con las extensiones de GNU C. Para tratar con esta situaci@'on, la opci@'on del compilador @option{-ansi} inhabilita las extensiones de que est@'an en conflicto con el est@'andar ANSI/ISO. Los sistemas que usan la GNU C Library (@code{glibc}) tambi@'en deshabilitan las extensiones a la librer@'{@dotless{i}}a est@'andar de C. Esto permite que los programas escritos para ANSI/ISO sean compilados sin efectos no deseados de extensiones de GNU. Por ejemplo, aqu@'{@dotless{i}} hay un programa ANSI/ISO C v@'alido que usa una variable llamada @code{asm}: @example @verbatiminclude ansi.es.c @end example @noindent El nombre de variable @code{asm} es v@'alido bajo el est@'andar ANSI/ISO, pero este programa no compilar@'a en GNU C porque @code{asm} es una palabra reservada de la extensi@'on GNU C (permite instrucciones de ensamblador nativas para ser usadas en funciones C). Por consiguiente, no puede ser usado como un nombre de variable sin dar un error de compilaci@'on: @cindex palabras reservadas, adicionales en GNU C @cindex error de an@'alisis sint@'actico debido a extensiones del lenguaje @example $ gcc -Wall ansi.c ansi.c: In function 'main': ansi.c:6:14: error: expected identifier or '(' before 'asm' ansi.c:7:39: error: expected expression before 'asm' @end example @noindent En contraste, usar la opci@'on @option{-ansi} inhabilita la palabra clave @code{asm}, y permite que el programa anterior sea compilado correctamente: @example $ gcc -Wall -ansi ansi.es.c $ ./a.out la cadena asm es '6502' @end example @noindent Por referencia, las palabras reservadas no est@'andar y las macros definidas por las extensiones GNU C son @code{asm}, @code{inline}, @code{typeof}, @code{unix} y @code{vax}. Se pueden encontrar m@'as detalles en el Manual de Referencia de GCC ``@cite{Using GCC}'' (@pxref{Lectura adicional}). @cindex @code{asm}, palabra reservada de extensi@'on @cindex @code{typeof}, palabra reservada de la extensi@'on GNU C @cindex @code{unix}, palabra reservada de la extensi@'on GNU C @cindex @code{vax}, palabra reservada de la extensi@'on GNU C El siguiente ejemplo muestra el efecto de la opci@'on @option{-ansi} en sistemas usando la GNU C Library, tales como sistemas GNU/Linux. El programa suguiente imprime el valor de pi, @math{\pi=3.14159...}, dado por la definici@'on del preprocesador @code{M_PI} en el fichero de cabecera @file{math.h}: @example @verbatiminclude pi.es.c @end example @noindent La constante @code{M_PI} no es parte de la librer@'{@dotless{i}}a est@'andar ANSI/ISO de C (viene de la versi@'on BSD de Unix). En este caso, el programa no compilar@'a con la opci@'on @option{-ansi}: @cindex error de identificador no declarado para la librer@'{@dotless{i}}a C, al usar la opci@'on @option{-ansi} @example $ gcc -Wall -ansi pi.c pi.c: In function 'main': pi.c:7:38: error: 'M_PI' undeclared (first use in this function) pi.c:7:38: note: each undeclared identifier is reported only once for each function it appears in @end example @noindent El programa puede ser compilado sin la opci@'on @option{-ansi}. En este caso tanto el lenguaje como las extensiones de librer@'{@dotless{i}}a est@'an habilitadas por defecto: @example $ gcc -Wall pi.es.c $ ./a.out el valor de pi es 3.141593 @end example @noindent Tambi@'en es posible compilar el programa usando ANSI/ISO C, habilitando s@'olo las extensiones en la GNU C Library. Esto puede ser logrado definiendo macros especiales, tales como @code{_GNU_SOURCE}, que habilita extensiones en GNU C Library:@footnote{La opci@'on @option{-D} para la definici@'on de macros ser@'a explicada en detalle en el siguiente cap@'{@dotless{i}}tulo.} @cindex macro @code{_GNU_SOURCE}, habilita extensiones a la GNU C Library @cindex macro @code{GNU_SOURCE} (@code{_GNU_SOURCE}), habilita extensiones a la GNU C Library @example $ gcc -Wall -ansi -D_GNU_SOURCE pi.es.c $ ./a.out el valor de pi es 3.141593 @end example @noindent @cindex macros de test de funcionalidad, GNU C Library @cindex GNU C Library, macros de test de funcionalidad @cindex extensiones POSIX, GNU C Library @cindex extensiones BSD, GNU C Library @cindex extensiones XOPEN, GNU C Library @cindex extensiones SVID, GNU C Library La GNU C Library (Librer@'{@dotless{i}}a GNU C) proporciona un n@'umero de estas macros (referidas como @dfn{macros de test de funcionalidad}) que permiten controlar a trav@'es del soporte para extensiones POSIX (@w{@code{_POSIX_C_SOURCE}}), extensiones BSD (@w{@code{_BSD_SOURCE}}), extensiones SVID (@w{@code{_SVID_SOURCE}}), extensiones XOPEN (@w{@code{_XOPEN_SOURCE}}) y extensiones GNU (@w{@code{_GNU_SOURCE}}). La macro @w{@code{_GNU_SOURCE}} habilita todas las extensiones juntas, siendo las extensiones precedentes al resto en los casos donde haya conflicto. Informaci@'on adicional acerca de las macros de test de funcionalidad puede ser encontrada en el @cite{GNU C Library Reference Manual} (@pxref{Lectura adicional}). @node ANSI/ISO estricto @subsection ANSI/ISO estricto @cindex @option{pedantic}, opci@'on @cindex ANSI/ISO C, opci@'on de diagn@'osticos pedantic @cindex ANSI/ISO C estricto, opci@'on @option{-pedantic} La opci@'on @option{-pedantic} del comando @code{gcc} en combinaci@'on con la opci@'on @option{-ansi} har@'a que @code{gcc} rechace todas las extensiones de GNU C, no s@'olo aquellas que son incompatibles con el est@'andar ANSI/ISO. Esto ayudar@'a a escribir programas portables que siguen el est@'andar ANSI/ISO. Aqu@'{@dotless{i}} hay un programa que usa arrays de tama@~no variables, una extensi@'on de GNU C. El array @code{x[n]} es declarado con un tama@~no especificado por la variable entera @code{n}. @cindex arrays de tama@~no variable @cindex tama@~no variable, arrays @example @verbatiminclude gnuarray.es.c @end example @noindent Este programa compilar@'a con la opci@'on @option{-ansi}, porque soporta arrays de tama@~no variable que no interfieren con la compilaci@'on de programas ANSI/ISO v@'alidos ---@'esta es una extensi@'on compatible hacia atr@'as: @example $ gcc -Wall -ansi gnuarray.es.c @end example @noindent Sin embargo, compilar con @option{-ansi -pedantic} devuelve avisos de las violaciones del est@'andar ANSI/ISO: @example $ gcc -Wall -ansi -pedantic gnuarray.es.c gnuarray.es.c: In function `main': gnuarray.es.c:5: warning: ISO C90 forbids variable-size array `x' @end example @noindent N@'otese que una ausencia de avisos con @option{-ansi -pedantic} no garantiza que un programa cumpla estrictamente con el est@'andar ANSI/ISO. El est@'andar en s@'{@dotless{i}} especifica s@'olo un limitado conjunto de circunstancias que deber@'{@dotless{i}}an generar diagn@'osticos, y estos son los que se informa con @option{-ansi -pedantic}. @node Seleccionando est@'andares espec@'{@dotless{i}}ficos @subsection Seleccionando est@'andares espec@'{@dotless{i}}ficos @cindex @option{-std}, opci@'on que selecciona un est@'andar espec@'{@dotless{i}}fico del lenguaje @cindex @option{std}, opci@'on que selecciona un est@'andar espec@'{@dotless{i}}fico del lenguaje @cindex @code{c89}/@code{c99}, seleccionado con @option{-std} @cindex @code{gnu89}/@code{gnu99}, seleccionado con @option{-std} @cindex @code{iso9899:1990}/@code{iso9899:1999}, seleccionado con @option{-std} @cindex seleccionando est@'andares espec@'{@dotless{i}}ficos del lenguaje, con @option{-std} @cindex est@'andares del lenguaje, seleccionando con @option{-std} El est@'andar espec@'{@dotless{i}}fico del lenguaje usado por GCC puede ser controlado con la opci@'on @option{-std}. Los siguientes est@'andares del lenguaje C son soportados: @table @asis @item @option{-std=c89} o @option{-std=iso9899:1990} El est@'andar original ANSI/ISO C (ANSI X3.159-1989, ISO/IEC 9899:1990). GCC incorpora las correcciones en los dos ISO Technical Corrigiendo al est@'andar original. @item @option{-std=iso9899:199409} El lenguaje est@'andar ISO de C con el ISO Amendment 1, publicado en 1994. Esta enmienda era concerniente principalmente con internacionalizaci@'on, tales como a@~nadir soporte para caracteres multi-byte a la librer@'{@dotless{i}}a C. @item @option{-std=c99} o @option{-std=iso9899:1999} El lenguaje est@'andar ISO de C, publicado en 1999 (ISO/IEC 9899:1999). @end table @noindent El lenguaje est@'andar de C con las extensiones de GNU puede ser seleccionado con las opciones @option{-std=gnu89} y @option{-std=gnu99}. @node Opciones de aviso en -Wall @section Opciones de aviso en @code{-Wall} @cindex opciones de aviso, en detalle Tal como se describi@'o antes (@pxref{Compilando un peque@~no programa C}), la opci@'on de aviso @option{-Wall} habilita avisos para muchos errores comunes, y siempre se deber@'{@dotless{i}}a usar. @option{-Wall} puede combinarse con un largo n@'umero de otras opciones de aviso, m@'as espec@'{@dotless{i}}ficas, que tambi@'en pueden ser seleccionadas individualmente. Aqu@'{@dotless{i}} hay un resumen de estas opciones: @table @asis @item @option{-Wcomment} @r{(incluida en @option{-Wall})} @cindex comentarios, anidados @cindex comentarios anidados, aviso de @cindex @option{-Wcomment}, opci@'on de aviso acerca de comentarios anidados @cindex @option{-Wcomment}, opci@'on de aviso acerca de comentarios anidados @cindex @option{comment}, opci@'on de aviso de comentarios anidados Esta opci@'on avisa acerca de comentarios anidados. Los comentarios anidados normalmente surgen cuando una secci@'on de c@'odigo contiene comentarios despu@'es de haber sido ya comentada: @example /* comienzo de comentario double x = 1.23 ; /* posici@'on x */ */ @end example @noindent Los comentarios anidados pueden ser una fuente de confusi@'on ---el camino seguro de ``comentar'' una secci@'on de c@'odigo que contiene comentarios es usar la directiva del preprocesador @code{#if 0 ... #endif} alrededor de ella: @cindex @code{#if}, directiva del preprocesador @example /* comentario exterior */ #if 0 double x = 1.23 ; /* posici@'on x */ #endif@end example @item @option{-Wformat} @r{(incluida en @option{-Wall})} @cindex @option{-Wformat}, opci@'on de aviso de formato de cadenas incorrecto @cindex formato de cadenas, aviso de uso incorrecto @cindex @code{printf}, aviso de uso incorrecto @cindex @code{scanf}, aviso de uso incorrecto Esta opci@'on avisa acerca del incorrecto uso del formato de cadenas en funciones tales como @code{printf} y @code{scanf}, donde el especificador de formato no concuerda con el tipo del correspondiente argumento de la funci@'on. @item @option{-Wunused} @r{(incluida en @option{-Wall})} @cindex aviso de variable no usada @cindex @option{-Wunused}, opci@'on de aviso de variable no usada @cindex @option{Wunused}, opci@'on de aviso de variable no usada Esta opci@'on avisa acerca de variables no usadas. Cuando una variable es declarada pero no se usa, puede ser debido a que otra variable ha sido accidentalmente sustituida en su lugar. Si la variable realmente no se necesita, @'esta pueder ser eliminada del c@'odigo fuente. @item @option{-Wimplicit} @r{(incluida en @option{-Wall})} @cindex @option{-Wimplicit}, opci@'on de aviso de declaraciones no encontradas @cindex @option{Wimplicit}, opci@'on de aviso de declaraciones no encontradas @cindex declaraci@'on impl@'{@dotless{i}}cita de funci@'on @cindex aviso de prototipos perdidos @cindex prototipos, perdidos Esta opci@'on avisa de cualquier funci@'on que es usada sin haber sido declarada. La raz@'on m@'as com@'un para que una funci@'on sea usada sin haber sido declarada es haber olvidado incluir un fichero de cabecera. @item @option{-Wreturn-type} @r{(incluida en @option{-Wall})} @cindex tipo devuelto, no v@'alido @cindex @code{return} vac@'{@dotless{i}}o, uso incorrecto de @cindex void @code{return}, uso incorrecto de @cindex @option{-Wreturn-type}, opci@'on de aviso de tipos devueltos incorrectos @cindex @option{Wreturn-type}, opci@'on de aviso de tipos devueltos incorrectos Esta opci@'on avisa de funciones que por su definici@'on no tienen tipo de retorno, pero no son declaradas como @code{void}. Tambi@'en avisa de sentencias con un @code{return} vac@'{@dotless{i}}o en funciones que no son declaradas @code{void}. Por ejemplo, el siguiente programa no usa un valor de retorno expl@'{@dotless{i}}cito: @example @verbatiminclude main4.es.c @end example @noindent La falta de un valor de retorno en el c@'odigo de arriba podr@'{@dotless{i}}a ser el resultado de una omisi@'on accidental por el programador ---el valor devuelto por la funci@'on main es el valor de retorno de la funci@'on @code{printf} (el n@'umero de caracteres impresos). Para evitar ambiguedad, es preferible usar un valor expl@'{@dotless{i}}cito en la sentencia de retorno, bien una variable, @'o bien una constante, como @code{return 0}. @end table El conjunto completo de opciones de aviso incluidas en @option{-Wall} puede encontrarse en el Manual de Referencia de GCC ``@cite{Using GCC}'' (@pxref{Lectura adicional}). Las opciones incluidas en @option{-Wall} tienen la caracter@'{@dotless{i}}stica com@'un de informar de construcciones son siempre err@'oneas, o pueden ser f@'acilmente reescritas en un inambiguo camino correcto. Esta es la raz@'on de que @'estos sean tan @'utiles ---cualquier aviso producido por @option{-Wall} puede ser tomado como una indicaci@'on de un potencial serio problema. @node Opciones de aviso adicionales @section Opciones de aviso adicionales @cindex opciones de avisos adicionales @cindex opciones de avisos, adicionales GCC proporciona muchas otras opciones de aviso que no son incluidas en @option{-Wall} pero que con frecuencia son @'utiles. Generalmente estas producen avisos para el c@'odigo fuente que puede ser t@'ecnicamente v@'alido, pero puede causar problemas. El criterio para estas opciones est@'a basado en la experiencia de errores comunes ---estos no son incluidos en @option{-Wall} s@'olo indican posibles problemas o c@'odigo ``sospechoso''. Debido a que estos avisos pueden ser resueltos con c@'odigo v@'alido no es necesario compilar con estas opciones todo el tiempo. Es m@'as apropiado usarlas peri@'odicamente y revisar los resultados, comprobando cualquier cosa inesperada, o habilitarlas para algunos programas o ficheros. @table @asis @item @option{-W} @cindex errores comunes, no incluidos con @option{-Wall} @cindex @option{-W}, opci@'on que habilita avisos adicionales @cindex @option{W}, opci@'on que habilita avisos adicionales @cindex avisos, addicionales con @option{-W} @cindex opci@'on de aviso, avisos adicionales @option{-W} Esta es una opci@'on general similar a @option{-Wall} que avisa acerca de una selecci@'on de errores comunes de programaci@'on, tales como funciones que no devuelven un valor, y comparaciones entre valores con y sin signo. Por ejemplo, la siguiente funci@'on comprueba si un entero sin signo es negativo (lo cual es imposible, claro): @example @verbatiminclude w.es.c @end example @noindent Tras compilar esta funci@'on con @option{-Wall} no se produce ning@'un aviso, @example $ gcc -Wall -c w.es.c @end example @noindent pero da un aviso con @option{-W}: @cindex comparaci@'on de expresiones de aviso always true/false @example $ gcc -W -c w.c w.c: In function 'foo': w.c:4:3: warning: comparison of unsigned expression < 0 is always false [-Wtype-limits] @end example @noindent En la pr@'actica, las opciones @option{-W} y @option{-Wall} se usan juntas. @item @option{-Wconversion} @cindex coversiones de tipo, aviso de de @cindex conversiones entre tipos, aviso de @cindex variable sin signo convertida a con signo, aviso de @cindex variable con signo convertida a sin signo, aviso de @cindex @option{-Wconversion}, opci@'on de aviso de conversiones de tipos @cindex @option{Wconversion}, opci@'on de aviso de conversiones de tipos Esta opci@'on avisa acerca de conversiones impl@'{@dotless{i}}citas de tipo que podr@'{@dotless{i}}an causar resultados inesperados, tales como conversiones entre tipos reales y enteros, entre tipos con y sin signo y entre tipos de diferente tama@~no (por ej. enteros long y short). Las conversiones pueden ocurrir en expresiones y asignaciones, y en llamadas a funciones si los tipos de los argumentos no concuerdan con aquellos especificados en el prototipo. Por ejemplo, el valor entero de la funci@'on absoluto @code{int abs(int i)} es f@'acilmente confundido con la correspondiente funci@'on de coma flotante @code{double fabs(double x)}. Esto puede traer resultados incorrectos, como muestra el siguiente programa: @example @verbatiminclude wabs.es.c @end example @noindent Tras compilar esta funci@'on con @option{-Wall} no se produce ning@'un aviso, @example $ gcc -Wall wabs.es.c $ ./a.out x = -3.14 |x| = 3 @r{(incorrecto)} @end example @noindent pero da un aviso con @option{-Wconversion}: @example $ gcc -Wall -Wconversion wabs.c wabs.c: In function 'main': wabs.c:8:3: warning: conversion to 'int' from 'double' may alter its value [-Wconversion] @end example La opci@'on @option{-Wconversion} tambi@'en captura errores tales como la asignaci@'on de un valor negativo a una variable sin signo, como en el siguiente c@'odigo, @example unsigned int x = -1; @end example @noindent @cindex casts, usados para evitar avisos de conversi@'on @cindex entero sin signo, casting @cindex entero con signo, casting Esto est@'a permitido t@'ecnicamente por el est@'andar ANSI/ISO C (con el entero negativo siendo convertido a entero positivo, de acuerdo a la representaci@'on de la m@'aquina) pero podr@'{@dotless{i}}a ser un simple error de programaci@'on. Si se necesita realizar tal conversi@'on se puede usar un cast expl@'{@dotless{i}}cito, tal como @code{(unsigned int)-1}, para evitar avisos con esta opci@'on. En m@'aquinas con complemento a dos el cast de @math{-1} da el m@'aximo n@'umero que puede ser representado por un entero sin signo. @item @option{-Wshadow} @cindex ocultamiento de variables @cindex variable oculta @cindex @option{-Wshadow}, opci@'on de aviso de variables ocultas @cindex @option{Wshadow}, opci@'on de aviso de variables ocultas Esta opci@'on avisa acerca de la redeclaraci@'on de un nombre de variable en un contexto en el que ha sido declarado. Esto define una variable @dfn{oculta}, y causa la confusi@'on de qu@'e ocurrencia de la variable corresponde a qu@'e valor. La siguiente funci@'on declara una variable local @code{y} que oculta la declaraci@'on en el cuerpo de la funci@'on: @example @verbatiminclude shadow.es.c @end example @noindent Esto es ANSI/ISO C v@'alido, y el valor devuelto es 1. La ocultaci@'on de la variable @code{y} podr@'{@dotless{i}}a parecer (de manera incorrecta) que el valor devuelto es @code{x}, al mirar la l@'{@dotless{i}}nea @code{y = x} (especialmente en una larga y complicada funci@'on). La ocultaci@'on tambi@'en puede ocurrir en nombres de funci@'on. Por ejemplo, el siguiente programa intenta definir una variable @code{sin} que oculta la funci@'on est@'andar @code{sin(x)}. @example @verbatiminclude shadow2.es.c @end example @noindent Este error ser@'a detectado con la opci@'on @option{-Wshadow}. @item @option{-Wcast-qual} @cindex calificadores, aviso de sobrescritura por casts @cindex @code{const}, aviso de sobreescritura por casts @cindex @option{-Wcast-qual}, opci@'on de aviso de casts eliminando calificadores @cindex @option{Wcast-qual}, opci@'on de aviso de casts eliminando calificadores Esta opci@'on avisa de punteros que son transformados para eliminar un calificador de tipo tal como @code{const}. Por ejemplo, la siguiente funci@'on descarta el calificador @code{const} desde su argumento de entrada, permiti@'endole ser sobreescrito: @example @verbatiminclude castqual.es.c @end example @noindent La modificaci@'on de los contenidos originales de @code{str} es una violaci@'on de la propiedad @code{const}. Esta opci@'on avisar@'a de la inapropiada transformaci@'on de la variable @code{str} que permite que la cadena sea modificada. @item @option{-Wwrite-strings} @cindex cadenas constantes con posibilidad de escritura, deshabilitando @cindex cadenas constantes, avisos en tiempo de compilaci@'on @cindex @option{-Wwrite-strings}, opci@'on de aviso para cadenas constantes modificadas @cindex @option{Wwrite-strings}, opci@'on de aviso para cadenas constantes modificadas Esta opci@'on impl@'{@dotless{i}}citamente da a todas las constantes definidas en el programa un calificador @code{const}, causando un aviso en tiempo de compilaci@'on si hay un intento de sobreescribirlo. El resultado de modificar una cadena constante no est@'a definido por el est@'andar ANSI/ISO, y el uso de constantes de cadena escribibles est@'a obsoleto en GCC. @cindex K&R dialecto de C, avisos de comportamiento diferente @cindex C tradicional (K&R), avisos de comportamiento diferente @cindex @option{-Wtraditional}, opci@'on de aviso de C tradicional @cindex @option{Wtraditional}, opci@'on de aviso de C tradicional @item @option{-Wtraditional} Esta opci@'on avisa acerca de partes de c@'odigo que deber@'{@dotless{i}}an ser interpretadas de manera diferente por un compilador ANSI/ISO y un compilador ``tradicional'' pre-ANSI.@footnote{La forma tradicional del lenguaje C fu@'e descrita en el manual de referencia original de C ``@cite{The C Programming Language (First Edition)}'' por Kernighan y Ritchie.} Cuando se mantiene software legado puede ser necesario investigar si en el c@'odigo original se pretend@'{@dotless{i}}a la interpretaci@'on ANSI/ISO o la tradicional para entender los avisos generados por esta opci@'on. @end table @noindent @cindex avisos, promoviendo errores @cindex compilaci@'on, parando en avisos @cindex @option{-Werror}, opci@'on que convierte avisos en errores @cindex @option{Werror}, opci@'on que convierte avisos en errores Las opciones anteriores producen mensajes de avisos de diagn@'ostico, pero permiten la compilaci@'on para continuar y producir un fichero objeto o ejecutable. Para programas grandes esto puede ser deseable para capturar todos los avisos deteniendo la compilaci@'on siempre que se genera un aviso. La opci@'on @option{-Werror} cambia el comportamiento por defecto al convertir los avisos en errores, parando la compilaci@'on siempre y cuando ocurra un aviso. @node Opciones de aviso recomendadas @section Opciones de aviso recomendadas Las siguiente opciones son una buena elecci@'on para encontrar problemas en programas C y C++: @example $ gcc -ansi -pedantic -Wall -W -Wconversion -Wshadow -Wcast-qual -Wwrite-strings @end example @noindent Aunque esta lista no es exhaustiva, el uso regular de estas opciones capturar@'a muchos errores comunes. @node Usando el preprocesador @chapter Usando el preprocesador @cindex @code{cpp}, preprocesador de C @cindex preprocesador, usando Este cap@'{@dotless{i}}tulo describe el uso del preprocesador C GNU @code{cpp}, que forma parte del paquete GCC. Este preprocesador expande las macros en los ficheros fuentes antes de ser compilados. Es invocado de forma autom@'atica cada vez que GCC procesa un programa C o C++.@footnote{En recientes versiones de GCC el preprocesador est@'a integrado dentro del compilador, aunque un comando por separado @command{cpp} est@'a siempre incluido.} @menu * Definiendo macros:: * Macros con valor:: * Preprocesando archivos fuentes:: @end menu @node Definiendo macros @section Definiendo macros @cindex definiendo macros @cindex macros, definici@'on en preprocesador @cindex @code{#define}, directiva del preprocesador @cindex @code{#ifdef}, directiva del preprocesador El siguiente programa demuestra el uso habitual del preprocesador C. Se usa la instrucci@'on condicional del preprocesador @code{#ifdef} para comprobar si la macro ya fu@'e definida: @example @verbatiminclude dtest.es.c @end example @noindent Cuando la macro est@'a definida, el preprocesador incluye el c@'odigo correspondiente antes del comando de cierre @code{#endif}. En este ejemplo la macro comprobada es llamada @code{TEST}, y la parte condicional del c@'odigo fuente es la instrucci@'on @code{printf} que imprime el mensaje ``@code{Modo test}''. La opci@'on de @code{gcc} @option{-D@var{NAME}} define una macro del preprocesador @code{NAME} desde la l@'{@dotless{i}}nea de comandos. Si el programa anterior es compilado con la opci@'on de l@'{@dotless{i}}nea de comandos @option{-DTEST}, la macro @code{TEST} ser@'a definida y el ejecutable resultante imprimir@'a ambos mensajes: @cindex @option{-D}, opci@'on para definir macros @cindex @option{D}, opci@'on para definir macros @example $ gcc -Wall -DTEST dtest.es.c $ ./a.out Modo test Ejecutando...@end example @noindent Si el programa es compilado sin la opci@'on @option{-D} entonces el mensaje ``@code{Modo test}'' se omite del c@'odigo fuente despu@'es del preproceso, y el ejecutable final no incluir@'a el c@'odigo para @'el: @example $ gcc -Wall dtest.es.c $ ./a.out Ejecutando... @end example @noindent @cindex espacio de nombres, prefijo reservado para el preprocesador Las macros est@'an generalmente indefinidas, a menos que sea especificada en la l@'{@dotless{i}}nea de comandos, o en un archivo fuente (o un archivo de cabecera de librer@'{@dotless{i}}a) con @code{#define}. Algunas macros son definidas de forma autom@'atica por el compilador ---habitualmente usan un espacio de nombres reservado comenzando con un prefijo de doble subrayado @samp{__}. El conjunto completo de macros predefinidas por el preprocesador puede ser listado ejecutanto el preprocesador @code{cpp} con la opci@'on @option{-dM} en un archivo vacio: @cindex macros predefinidas @cindex predefinidas, macros @cindex @option{-dM}, opci@'on que lista las macros predefinidas @cindex @option{dM}, opci@'on que lista de macros predefinidas @example $ cpp -dM /dev/null #define __i586 1 #define __WINT_MAX__ 4294967295U #define __ORDER_LITTLE_ENDIAN__ 1234 #define __SIZE_MAX__ 4294967295U ....... @end example @noindent Obs@'ervese que este listado incluye un peque@~no n@'umero de macros espec@'{@dotless{i}}ficas del sistema definidas por @code{gcc} que no usan el prefijo de doble subrayado. Estas macros no est@'andar pueden ser deshabilitadas con la opci@'on @option{-ansi} de @code{gcc}. @cindex macros predefinidas espec@'{@dotless{i}}ficas del sistema @node Macros con valor @section Macros con valor @cindex valor, de macro @cindex macros, definidas con valor Cuando es definida, una macro puede adem@'as tener asignado un valor. Este valor es sustituido dentro del c@'odigo fuente en cada lugar donde aparezca la macro. El siguiente programa usa la macro @code{NUM}, para representar que ser@'a impreso: @example @verbatiminclude dtestval.es.c @end example @noindent Observe las macros no se expanden dentro de la cadena ---solo la ocurrencia de @code{NUM} fuera de la cadena es sustituida por el preprocesador. Para definir una macro con un valor, se usa la opci@'on @option{-D} en la l@'{@dotless{i}}nea de comandos en la forma @option{-D@var{NAME}=@var{VALUE}}. Por ejemplo, la siguiente l@'{@dotless{i}}nea de comandos define @code{NUM} a 100 mientras se compila el programa anterior: @example $ gcc -Wall -DNUM=100 dtestval.es.c $ ./a.out El valor de NUM es 100 @end example @noindent Este ejemplo usa un n@'umero, pero una macro puede tomar valores de cualquier forma. Cuando el valor de un macro est@'a asignado, @'este es insertado directamente dentro del c@'odigo fuente donde la macro aparezca. Por ejemplo, la siguiente definici@'on expande las ocurrencias de @code{NUM} a @code{2+2} durante el preprocesamiento: @example $ gcc -Wall -DNUM="2+2" dtestval.es.c $ ./a.out El valor de NUM es 4@end example @noindent Una vez que el preprocesador ha realizado la sustituci@'on @code{NUM @expansion{} 2+2} es equivalente a compilar el siguiente programa: @example @verbatiminclude dtestval2.es.c @end example @noindent @noindent Observe que una buena idea es encerrar las macros entre par@'entesis siempre que formen parte de una expresi@'on. Por ejemplo, el programa siguiente usa par@'entesis para asegurar la correcta precedencia para la multiplicaci@'on @code{10*NUM}: @cindex precedencia, al usar preprocesador @example @verbatiminclude dtestval3.es.c @end example @noindent Con estos par@'entesis, se produce el resultado esperado cuando se compila con la misma l@'{@dotless{i}}nea de comandos anterior: @example $ gcc -Wall -DNUM="2+2" dtestval3.es.c $ ./a.out Diez veces NUM es 40@end example @noindent Sin los par@'entesis, el programa hubiera producido el valor @code{22} desde la forma literal de la expresi@'on @code{10*2+2 = 22}, en vez del valor deseado @code{10*(2+2) = 40}. Cuando una macro es definida solo con la opci@'on @option{-D}, @code{gcc} usa el valor por defecto @code{1}. Por ejemplo, compilando el programa test original con la opci@'on @option{-DNUM} se genera un ejecutable que produce la siguiente salida: @cindex valor por defecto, de macro definido con @option{-D} @cindex macros, valor por defecto de @cindex macros del preprocesador, valor por defecto de @example $ gcc -Wall -DNUM dtestval.es.c $ ./a.out El valor de NUM es 1 @end example @noindent @cindex comillas, para definir una macro vac@'{@dotless{i}}a Una macro puede ser definida con un valor vacio usando comillas en la l@'{@dotless{i}}nea de comandos, @code{-D@var{NAME}=""}. Tal macro ser@'a tratada como @i{definida} por las instrucciones condicionales, tal como @code{#ifdef}, pero no se expande en nada. @cindex macro vac@'{@dotless{i}}a, comparada con macro indefinida @cindex macro indefinida, comparada con macro vac@'{@dotless{i}}a Una macro que contenga comillas se puede definir usando el car@'acter de escape de la shell. Por ejemplo, la opci@'on @code{-DMESSAGE='"@exclamdown{}Hola, Mundo!"'} define una macro @code{MESSAGE} que se expandir@'a en la secuencia de caracteres @code{"@exclamdown{}Hola, Mundo!"}. Los caracteres de escape @code{'...'} protegen los comillas de la cadena @code{"@exclamdown{}Hola, Mundo!"}. Para una explicaci@'on de los diferentes tipos de comillas y secuencias de escape usandas en la shell vea ``@cite{GNU Bash Reference Manual}'',@ref{Lectura adicional}. @cindex comillas en la shell @node Preprocesando archivos fuentes @section Preprocesando archivos fuentes @cindex @option{-E}, opci@'on para preprocesar ficheros fuente @cindex @option{E}, opci@'on para preprocesar ficheros fuente @cindex preprocesamiento de ficheros fuente, opci@'on @option{-E} Es posible ver el efecto del preprocesador en los archivos fuentes directamente, usando la opci@'on @option{-E} de @code{gcc}. Por ejemplo, el fichero siguiente define y usa la macro @code{TEST}: @example @verbatiminclude test.es.c @end example @noindent Si este fichero se llama @file{test.es.c} el efecto del preprocesador puede ser visto con la siguiente l@'{@dotless{i}}nea de comandos: @example $ gcc -E test.es.c # 1 "test.es.c" # 1 "" # 1 "" # 1 "test.es.c" const char str[] = "@exclamdown{}Hola, Mundo!"; @end example @noindent La opci@'on @option{-E} causa que @code{gcc} ejecute el preprocesador, muestre la salida expandida, y termine sin compilar el c@'odigo fuente resultante. El valor de la macro @code{TEST} es sustituido directamente en la salida, produciendo la secuencia de caracteres @code{const char str[] = "@exclamdown{}Hola, Mundo!" ;}. @cindex n@'umeros de l@'{@dotless{i}}nea, grabados en ficheros preprocesados El preprocesador adem@'as inserta l@'{@dotless{i}}neas de registro del archivo fuente y el n@'umero de l@'{@dotless{i}}nea en la forma @code{# @var{n@'umero-de-l@'{@dotless{i}}nea} "@var{archivo-fuente}"}, para ayudar en la depuraci@'on y permite al compilador mostrar los mensajes de error referentes a esta informaci@'on. Estas l@'{@dotless{i}}neas no afectan al programa en s@'{@dotless{i}}. La posibilidad de ver los archivos fuentes precompilados puede resultar @'util para examinar los efectos de los archivos de cabeceras del sistema, y encontrar las declaraciones de las funciones del sistema. El siguiente programa incluye el archivo de cabecera @file{stdio.h} para obtener la declaraci@'on de la funci@'on @code{printf}: @example @verbatiminclude hola.es.c @end example @noindent Es posible examinar las declaraciones incluidas en los archivos de cabeceras preprocesando el archivo con @code{gcc -E}: @example $ gcc -E hola.es.c @end example @noindent En un sistema GNU, esto produce una salida similar a lo siguiente: @example # 1 "hola.es.c" # 1 "/usr/include/stdio.h" 1 3 extern FILE *stdin; extern FILE *stdout; extern FILE *stderr; extern int fprintf (FILE * __stream, const char * __format, ...) ; extern int printf (const char * __format, ...) ; @r{@i{[ ... declaraciones adicionales ... ]}} # 1 "hola.es.c" 2 int main (void) @{ printf ("@exclamdown{}Hola, Mundo!"); return 0; @} @end example @noindent Los archivos de cabeceras del sistema preprocesados suelen generar una extensa salida. @'Esta puede ser redirigida a un archivo, o almacenada m@'as convenientemente usando la opci@'on @option{-save-temps}: @cindex @option{-save-temps}, opci@'on que guarda ficheros intermedios @cindex @option{save-temps}, opci@'on que guarda ficheros intermedios @cindex ficheros preprocesados, guardando @cindex ficheros intermedios, guardando @cindex ficheros temporales, guardando @example $ gcc -c -save-temps hola.es.c@end example @noindent Despu@'es de ejecutar este comando, la salida del preprocesador estar@'a disponible en el archivo @file{hola.i}. La opci@'on @option{-save-temps} adem@'as almacena los archivos de ensamblado @file{.s} y los archivos objetos @file{.o} adem@'as de los archivos preprocesados @file{.i}. @node Compilando para depuraci@'on @chapter Compilando para depuraci@'on @cindex depurando, flags de compilaci@'on @cindex @option{-g}, opci@'on que activa la depuraci@'on @cindex @option{g}, opci@'on que activa la depuraci@'on @cindex compilaci@'on, para depuraci@'on Normalmente, un archivo ejecutable no contiene ninguna referencia del archivo fuente original, tal como nombres de variables o n@'umeros de l@'{@dotless{i}}nea ---el archivo ejecutable es una simple secuencia de instrucciones en c@'odigo m@'aquina producidas por el compilador. Esto es insuficiente para depuraci@'on, ya que no es una tarea f@'acil la forma de encontrar la causa del fallo en un programa. @cindex @code{gdb} @cindex depuraci@'on, con @code{gdb} @cindex GNU debugger, @code{gdb} @cindex tabla de s@'{@dotless{i}}mbolos @cindex ejecutable, tabla de s@'{@dotless{i}}mbolos almacenada en GCC proporciona la @dfn{opci@'on de depuraci@'on} @option{-g} para guardar informaci@'on de depuraci@'on en los archivos objetos y ejecutables. Esta informaci@'on de depuraci@'on permite seguir la pista de los errores desde una instrucci@'on espec@'{@dotless{i}}fica a la correspondiente l@'{@dotless{i}}nea en el c@'odigo fuente original. La ejecuci@'on de un programa compilado con @option{-g} puede ser seguido por un depurador, tal como el Depurador GNU @code{gdb} (para m@'as informac@'on vea ``@cite{Debugging with GDB: The GNU Source-Level Debugger}'', @ref{Lectura adicional}). Usando un depurador es posible examinar los valores de las variables mientras est@'a en ejecuci@'on un programa. La opci@'on de depuraci@'on del compilador funciona almacenando los nombres de funciones y variables y las l@'{@dotless{i}}neas del c@'odigo fuente en una @dfn{tabla de s@'{@dotless{i}}mbolos} en el archivo objeto o ejecutable. @menu * Examinando archivos core:: * Mostrando un rastreo:: * Poniendo un punto de ruptura:: * Paso a paso a trav@'es de un programa:: * Modificando variables:: * Continuando la ejecuci@'on:: * M@'as informaci@'on de GDB:: @end menu @node Examinando archivos core @section Examinando archivos core @cindex fichero core, examinando @cindex fallos, salvado en archivo core @cindex fallos de programa, salvado en archivo core @cindex examinando ficheros core Adicionalmente a permitir que un programa se ejecute en un depurador, un importante beneficio de la opci@'on @option{-g} es que permite examinar la causa del fallo de un programa a trav@'es de un ``core dump''. @cindex terminaci@'on, anormal (@code{core dumped}) Cuando un programa termina de forma anormal (p.e. un fallo) el sistema operativo puede escribir un @dfn{core file} (habitualmente llamado @file{core}) que contiene el estado de memoria del programa en el momento del fallo. Este fichero es a menudo referido como un @dfn{core dump}.@footnote{Esta terminolog@'{@dotless{i}}a data de los tiempos de las memorias magn@'eticas.} Combinada con la informaci@'on de la tabla de s@'{@dotless{i}}mbolos producida por la opci@'on @option{-g}, se puede usar el core dump para encontrar la l@'{@dotless{i}}nea donde el programa se par@'o, y los valores de las variables en este punto. @cindex despliegue, opciones para Esto es muy usado tanto durante el desarrollo de software como despu@'es del desarrollo ---permite investigar los problemas cuando un programa falla ``a pi@'e de campo''. Aqu@'{@dotless{i}} hay un simple ejemplo de un programa que contiene un fallo de acceso inv@'alido a memoria, el cual se usar@'a para producir un archivo core dump: @example @verbatiminclude null.es.c @end example @noindent @cindex desreferenciando, puntero nulo @cindex puntero nulo @cindex error, ejemplo de Este programa intenta referenciar un puntero nulo @code{p}, lo cual es una operaci@'on inv@'alida. En la mayor@'{@dotless{i}}a de lo sistemas operativos, esto causa un fallo del programa. @footnote{Hist@'oricamente, un puntero nulo correspond@'{@dotless{i}}a con la posici@'on 0 de memoria, la cual es normalmente restringida por el kernel del sistema operativo. En la pr@'actica no siempre es as@'{@dotless{i}} como se trata un puntero nulo, pero el resultado es habitualmente el mismo.} Para que sea posible encontrar la causa de un posterior fallo, se necesitar@'a compilar el programa con la opci@'on @option{-g}: @example $ gcc -Wall -g null.es.c @end example @noindent Observe que el puntero nulo s@'olo causar@'a un problema en tiempo de ejecuci@'on, as@'{@dotless{i}} la opci@'on @option{-Wall} no producir@'a ning@'un aviso. Haciendo correr el archivo ejecutable en un sistema x86 GNU/Linux causar@'a que el sistema operativo lo finalice de forma anormal: @cindex segmentation fault @example $ ./a.out Segmentation fault (core dumped) @end example @noindent Siempre que aparezca el mensaje @samp{core dumped}, el sistema operativo producir@'a un archivo denominado @file{core} en el directorio en curso. @footnote{Algunos sistemas, tales como FreeBSD y Solaris, se pueden configurados para escribir los archivos core en directorios espec@'{@dotless{i}}ficos, p.e. @file{/var/coredumps/}, usando los comandos @code{sysctl} y @code{coreadm}.} Este archivo core contiene una copia completa de las p@'aginas de memoria que el programa manten@'{@dotless{i}}a en el momento de su finalizaci@'on. A prop@'osito, el t@'ermino @dfn{segmentation fault} se refiere al hecho de que el programa intent@'o un acceso a un ``segmento'' de memoria restringido fuera del @'area de memoria que tiene reservada para @'el. @cindex fichero core, no se produce @cindex comando @command{ulimit} Algunos sistemas est@'an configurados para no escribir archivos core por defecto, debido a que los archivos pueden ser muy grandes y r@'apidamente ocupan el espacio disponible en los discos de un sistema. En la shell @cite{GNU Bash} el comando @code{ulimit -c} controla el tama@~no m@'aximo de los archivos core. Si el l@'{@dotless{i}}mite de tama@~no es 0, no se producir@'an archivos core. El tama@~no l@'{@dotless{i}}mite actual se puede mostrar introduciendo el siguiente comando: @cindex @code{tcsh}, comando limit @example $ ulimit -c 0 @end example @noindent Si el resultado es cero, como se mostr@'o anteriormente, entonces puede ser incrementado con el siguiente comando para permitir escribir archivos core de cualquier tama@~no: @footnote{Este ejemplo usa el comando @code{ulimit} en la Bash shell GNU. En otros sistemas operativos el uso de @code{ulimit} puede variar, y tener un nombre diferente (la shell @code{tcsh} a su vez, usa el nombre @code{limit}). El tama@~no l@'{@dotless{i}}mite de los archivos core puede ser puesto a un valor espec@'{@dotless{i}}fico en kilobytes.} @example $ ulimit -c unlimited @end example @noindent Observe que esta configuraci@'on solo aplica en la shell actual. Para poner l@'{@dotless{i}}mite en futuras sesiones el comando se deber@'a poner en el archivo adecuado de entrada al sistema, tal como @file{.bash_profile} para la Bash shell GNU. @cindex fichero @code{bash} profile @cindex fichero core, examinando @cindex @code{gdb}, depurando ficheros core con Los archivos core pueden ser cargados por el Depurador GNU @code{gdb} con el siguiente comando: @example $ gdb @var{FICHERO-EJECUTABLE} @var{FICHERO-CORE} @end example @noindent Observe que tanto el archivo ejecutable original como el archivo core son requeridos para la depuraci@'on ---no es posible depurar un archivo core sin el correspondiente ejecutable. En este ejemplo, podemos cargar los archivos ejecutable y core con el comando: @example $ gdb a.out core @end example @noindent El depurador inmediatamente comienza a imprimir informaci@'on de diagn@'ostico, y muestra un listado de la l@'{@dotless{i}}nea donde el programa ha fallado (l@'{@dotless{i}}nea 13): @example $ gdb a.out core Core was generated by `./a.out'. Program terminated with signal 11, Segmentation fault Reading symbols from /lib/libc.so.6...done. Loaded symbols for /lib/libc.so.6 Reading symbols from /lib/ld-linux.so.2...done. Loaded symbols for /lib/ld-linux.so.2 #0 0x080483ed in foo (p=0x0) at null.es.c:13 13 int y = *p; (gdb)@end example @noindent La l@'{@dotless{i}}nea final @code{(dbg)} es el prompt del depurador GNU ---indica que se pueden introducir posteriores comandos en este punto.@footnote{Los detalles de la salida de diagn@'ostico pueden variar ligeramente dependiendo de que versi@'on de @code{gdb} est@'e usando.} Para investigar la causa del fallo, mostramos el valor del puntero @code{p} usando el comando @code{print} del depurador: @cindex @code{print} comando para depurar @example (gdb) print p $1 = (int *) 0x0 @end example @noindent Se muestra que @code{p} es un puntero nulo (@code{0x0}) del tipo @samp{int *}, as@'{@dotless{i}} nosotros sabemos que la referencia a @'el con la expresi@'on @code{p} en esta l@'{@dotless{i}}nea a causado el fallo. @node Mostrando un rastreo @section Mostrando un rastreo @cindex mostrando una traza @cindex traza, mostrando @cindex pila de rastreo, mostrando @cindex @code{backtrace}, comando para depurar El depurador puede mostrar las llamadas a funciones y sus argumentos hasta el punto actual de ejecuci@'on ---esto es llamado @dfn{pila de rastreo} (stack backtrace) y se muestra con el comando @code{backtrace}: @example (gdb) backtrace #0 0x080483ed in foo (p=0x0) at null.es.c:13 #1 0x080483d9 in main () at null.es.c:7 @end example @noindent En este caso, la pila de llamadas muestra que el fallo ocurri@'o en la l@'{@dotless{i}}nea 13 despu@'es de que la funci@'on @code{foo} fuera llamada desde @code{main} con el argumento @code{p=0x0} en la l@'{@dotless{i}}nea 7 de @file{null.es.c}. Es posible moverse por los diferentes niveles de la pila de llamadas, usando los comandos del depurador @code{up} y @code{down}. @node Poniendo un punto de ruptura @section Poniendo un punto de ruptura @cindex @code{break}, comando en @code{gdb} @cindex puntos de ruptura, definici@'on de @cindex parando la ejecuci@'on, con puntos de ruptura en @code{gdb} Un @dfn{punto de ruptura} (breakpoint) detiene la ejecuci@'on del programa y devuelve el control al depurador, donde las variables y la memoria pueden ser examinadas antes de continuar. Los puntos de ruptura pueden ponerse en funciones espec@'{@dotless{i}}ficas, l@'{@dotless{i}}neas o localizaciones de memoria con el comando @code{break}. Para poner un breakpoint en una funci@'on, usa el comando @code{break @var{function-name}}. Por ejemplo, el siguiente comando pone un breakpoint al inicio de la funci@'on @code{main} en el programa anterior: @example $ gdb a.out (gdb) break main Breakpoint 1 at 0x80483c6: file null.es.c, line 6. @end example @noindent El depurador tomar@'a el control del programa cuando la funci@'on @code{main} sea llamada. Como la funci@'on @code{main} es la primera funci@'on en ser ejecutada en un programa C, el programa se detendr@'a inmediatamente cuando se ejecute: @example (gdb) run Starting program: a.out Breakpoint 1, main () at null.es.c:6 6 int *p = 0; /* null pointer */ (gdb) @end example @noindent La consola muestra la l@'{@dotless{i}}nea que ser@'a ejecutada en siguiente lugar (el n@'umero de l@'{@dotless{i}}nea se muestra a la izquierda). El breakpoint detiene el programa @emph{antes} de ejecutar la l@'{@dotless{i}}nea, en este instante el puntero @code{p} est@'a indefinido y no ha sido puesto a cero a@'un. @node Paso a paso a trav@'es de un programa @section Paso a paso a trav@'es de un programa @cindex @code{step}, comando en @code{gdb} @cindex @code{next}, comando en @code{gdb} Para avanzar y ejecutar la l@'{@dotless{i}}nea mostrada anteriormente, usa el comando @code{step}: @example (gdb) step 7 return foo (p); @end example @noindent Despu@'es de ejecutar la l@'{@dotless{i}}nea 6, el depurador muestra la siguiente l@'{@dotless{i}}nea que ser@'a ejecutada. El puntero @code{p} est@'a ahora puesto a cero (null): @example (gdb) print p $1 = (int *) 0x0 @end example @noindent El comando @code{step} continuar@'a la ejecuci@'on del programa interactivamente a trav@'es de cualquier funci@'on que sea invocada en la l@'{@dotless{i}}nea actual. Si desea avanzar sin hacer un seguimiento de estas llamadas a funciones, use en cambio el comando @code{next}. @node Modificando variables @section Modificando variables @cindex @code{set}, comando en @code{gdb} Para arreglar temporalmente el fallo del puntero nulo descubierto anteriormente, podemos cambiar el valor de @code{p} en el programa en ejecuci@'on usando el comando @code{set variable}. Las variables pueden ser inicializadas a un valor espec@'{@dotless{i}}fico, o ser el resultado de una expresi@'on, la cual puede incluir llamadas a funciones. Esta poderosa caracter@'{@dotless{i}}stica permite a las funciones de un programa ser testeadas interactivamente a trav@'es del depurador. En este caso, interactivamente, se reservar@'a algo de memoria para el puntero @code{p} usando la funci@'on @code{malloc}, almacenando el valor 255 en la localizaci@'on de memoria resultante: @example (gdb) set variable p = malloc(sizeof(int)) (gdb) print p $2 = (int *) 0x40013f98 @r{(direcci@'on reservada por @code{malloc})} (gdb) set variable *p = 255 (gdb) print *p $3 = 255@end example @noindent Si ahora continuamos avanzando en el programa con el nuevo valor de @code{p} el anterior fallo de segmentaci@'on no se producir@'a: @example (gdb) step foo (p=0x40013f98) at null.es.c:13 13 int y = *p; (gdb) step 14 return y; @end example @node Continuando la ejecuci@'on @section Continuando la ejecuci@'on @cindex @code{finish}, comando en @code{gdb} @cindex @code{continue}, comando en @code{gdb} El comando @code{finish} continua la ejecuci@'on hasta el final de la actual funci@'on, mostrando el valor de retorno: @example (gdb) finish Run till exit from #0 0x08048400 in foo (p=0x40013f98) at null.es.c:15 0x080483d9 in main () at null.es.c:7 7 return foo (p); Value returned is $13 = 255 @end example @noindent @cindex c@'odigo exit, mostrado en @code{gdb} Para continuar la ejecuci@'on hasta que el programa termine (o hasta el siguiente breakpoint) use el comando @code{continue}, @example (gdb) continue Continuing. Program exited with code 0377. @end example @noindent Observe que el c@'odigo de salida se muestra en notaci@'on octal (0377 base 8 = 255 en base 10). @node M@'as informaci@'on de GDB @section M@'as informaci@'on @cindex Emacs, modo @code{gdb} @cindex @code{gdb}, modo Emacs @cindex @code{gdb}, interfaz gr@'afica @cindex Insight, Interfaz gr@'afica para @code{gdb} Por simplicidad, los ejemplos de este cap@'{@dotless{i}}tulo demuestran como usar @code{gdb} en la l@'{@dotless{i}}nea de comandos. Existen poderosas herramientas como Emacs en modo @sc{gdb} (@kbd{M-x gdb}), @sc{ddd} o @sc{insight}, interfaces gr@'aficos de @code{gdb}. Los enlaces a estos programas se puede encontrar en la p@'agina web del editor de este libro.@footnote{@uref{http://www.network-theory.co.uk/gcc/intro/}} Una completa descripci@'on de todos los comandos disponibles en @code{gdb} se puede encontrar en el manual ``@cite{Debugging with GDB: The GNU Soure-Level Debugger}'' (@pxref{Lectura adicional}). @node Compilando con optimizaci@'on @chapter Compilando con optimizaci@'on @cindex optimizaci@'on, explicaci@'on de @cindex compilando con optimizaci@'on GCC es un @dfn{compilador de optimizaci@'on}. Suministra un @'amplio rango de opciones que ayudan a incrementar la velocidad, o reducir el tama@~no, de los archivos ejecutables generados. La optimizaci@'on es un proceso complejo. Para cada comando de alto nivel en el c@'odigo fuente normalmente hay muchas combinaciones posibles de instrucciones m@'aquina que pueden ser usadas para alcanzar los resultados finales apropiados. El compilador debe considerar todas estas posibilidades y elegir entre ellas. En general, diferente c@'odigo es generado para diferentes procesadores, ya que usan ensambladores y lenguajes m@'aquina incompatibles. Cada tipo de procesador tiene sus propias caracter@'{@dotless{i}}sticas ---Algunas CPUs proporcionan un gran n@'umero de @dfn{registros} para manejar los resultados intermedios de c@'alculos, mientras que otros muchos deben almacenar y recuperar los resultados intermedios de la memoria. El c@'odigo apropiado debe generarse en cada caso. Adem@'as, diferentes instrucciones necesitan diferentes cantidades de tiempo, dependiendo de como fueron ordenadas. GCC, cuando compila con optimizaci@'on, toma estos factores en cuenta e intenta producir el ejecutable m@'as r@'apido para un sistema determinado. @menu * Optimizaci@'on a nivel de fuentes:: * Dilema velocidad-espacio:: * Planificaci@'on:: * Niveles de optimizaci@'on:: * Ejemplos de optimizaci@'on:: * Optimizaci@'on y depuraci@'on:: * Optimizaci@'on y avisos del compilador:: @end menu @node Optimizaci@'on a nivel de fuentes @section Optimizaci@'on a nivel de fuentes @cindex optimizaci@'on a nivel de c@'odigo La primera forma de optimizaci@'on usada por GCC sucede a nivel de c@'odigo fuente, y no requiere ning@'un conocimiento de las instrucciones m@'aquina. Hay muchas t@'ecnicas de optimizaci@'on a nivel de c@'odigo fuente ---esta secci@'on describe dos formas comunes: @dfn{eliminaci@'on de subexpresi@'on com@'un} y @dfn{expansi@'on de funci@'on en l@'{@dotless{i}}nea}. @subsection Eliminaci@'on de subexpresi@'on com@'un @cindex eliminaci@'on de subexpresi@'on com@'un, optimizaci@'on @cindex optimizaci@'on, eliminaci@'on de subexpresi@'on com@'un @cindex eliminaci@'on de subexpresi@'on, optimizaci@'on @cindex eliminaci@'on, de subexpresiones comunes Un m@'etodo de optimizaci@'on a nivel de c@'odigo fuente f@'acil de comprender implica el tratamiento de expresiones en el c@'odigo fuente con menor n@'umero de instrucciones, reutilizando resultados ya calculados. Por ejemplo, la siguiente asignaci@'on: @example x = cos(v)*(1+sin(u/2)) + sin(w)*(1-sin(u/2)) @end example @noindent puede ser reescrita con una variable temporal @code{t} y as@'{@dotless{i}} eliminar evaluaciones extras innecesarias del t@'ermino @code{sin(u/2)}: @example t = sin(u/2) x = cos(v)*(1+t) + sin(w)*(1-t) @end example @noindent Esta reescritura es denominada @dfn{eliminaci@'on de subexpresiones comunes} (CSE)@footnote{Nota del traductor: Siglas en ingl@'es de `Common Subexpression Elimination'}, y se realiza de forma autom@'atica cuando la optimizaci@'on est@'a activa.@footnote{Los valores introducidos temporalmente por el compilador durante la eliminaci@'on de subexpresiones comunes son usados s@'olo internamente, y no afectan a las variables reales. El nombre de la variable temporal @code{t} mostrado anteriormente s@'olo es a modo ilustrativo} La eliminaci@'on de subexpresiones comunes es beneficiosa porque simult@'aneamente incrementa la velocidad y reduce el tama@~no del c@'odigo. @subsection Expansi@'on de funci@'on en l@'{@dotless{i}}nea @cindex expansi@'on de funci@'on en l@'{@dotless{i}}nea, ejemplo de optimizaci@'on @cindex expansi@'on en l@'{@dotless{i}}nea, ejemplo de optimizaci@'on @comment An example of speed-space tradeoffs occurs with an optimization called @comment @dfn{function inlining}. Otro tipo de optimizaci@'on a nivel de c@'odigo fuente, denominada @dfn{expansi@'on de funci@'on en l@'{@dotless{i}}nea}, incrementa la eficiencia de la llamadas a funciones frecuentes. Cuando una funci@'on se invoca, se requiere una cierta cantidad de tiempo extra de CPU para llevar a cabo la llamada: se almacenan los argumentos de la funci@'on en los apropiados registros y localizaciones de memoria, se salta al inicio de la funci@'on (trayendo las adecuadas p@'aginas de memoria virtual en memoria f@'{@dotless{i}}sica @'o en la cach@'e de la CPU si fuera necesario), comienza la ejecuci@'on del c@'odigo, y se vuelve al punto original de ejecuci@'on donde la llamada a la funci@'on se completa. Este trabajo adicional es llamado @dfn{sobrecarga de la llamada a funci@'on}. La @dfn{expansi@'on de funci@'on en l@'{@dotless{i}}nea} elimina esta sobrecarga sustituyendo llamadas a funciones por el c@'odigo mismo de la funci@'on (conocido como poner el c@'odigo @dfn{en-l@'{@dotless{i}}nea}). @cindex sobrecarga de las llamadas a funciones @cindex sobrecarga, desde llamada a funci@'on En la mayor@'{@dotless{i}}a de los casos, la sobrecarga de las llamadas a funciones es una fracci@'on insignificante del total de tiempo de ejecuci@'on de un programa. Puede ser significativo s@'olo cuando las funciones contienen relativamente pocas instrucciones y emplean una fracci@'on sustancial de tiempo de ejecuci@'on ---en este caso la sobrecarga llega a ser una mayor proporci@'on del tiempo de ejecuci@'on. La expansi@'on de funciones en l@'{@dotless{i}}nea son siempre favorables si hay un @'unico punto de invocaci@'on a la funci@'on. Esto es incondicionalmente mejor si la invocaci@'on a una funci@'on requiere m@'as instrucciones (memoria) que mover el cuerpo de la funci@'on en linea. Esto es una situaci@'on habitual para una simple funci@'on de acceso en C++, lo cual puede beneficiar mucho a las funciones en l@'{@dotless{i}}nea. Por otra parte, las funciones en l@'{@dotless{i}}nea pueden facilitar optimizaciones futuras, como la eliminaci@'on de subexpresiones comunes, mezclando varias funciones separadas en un sencilla funci@'on m@'as grande. La siguiente funci@'on @code{sq(x)} es un t@'{@dotless{i}}pico ejemplo de una funci@'on que se beneficiar@'{@dotless{i}}a de la expansi@'on de funci@'on en l@'{@dotless{i}}nea. Calcula @math{x^2}, el cuadrado del argumento @math{x}: @example double sq (double x) @{ return x * x; @} @end example @noindent Esta funci@'on es peque@~na, as@'{@dotless{i}} la sobrecarga de la llamada es comparable al tiempo tomado en ejecutar una simple multiplicaci@'on fuera de la funci@'on misma. Si esta funci@'on se invoca dentro de un bucle, tal y como sucede m@'as abajo, entonces la sobrecarga de la llamada a la funci@'on llegar@'{@dotless{i}}a a ser sustancial: @example for (i = 0; i < 1000000; i++) @{ sum += sq (i + 0.5); @} @end example @noindent La optimizaci@'on con expansi@'on de funci@'on en l@'{@dotless{i}}nea reemplaza el interior del bucle del programa con el cuerpo de la funci@'on, dando el siguiente c@'odigo: @example for (i = 0; i < 1000000; i++) @{ double t = (i + 0.5); /* variable temporal */ sum += t * t; @} @end example @noindent La eliminaci@'on de la llamada a la funci@'on y realizar la multiplicaci@'on @dfn{en l@'{@dotless{i}}nea} permite al bucle ejecutarse con m@'axima eficiencia. GCC selecciona funciones para poner expandir en l@'{@dotless{i}}nea usando un n@'umero de heur@'{@dotless{i}}sticas, tal como funciones que son adecuadamente peque@~nas. Como optimizaci@'on, las funciones en l@'{@dotless{i}}nea son llevadas a cabo s@'olo dentro del archivo objeto. La palabra reservada @code{inline} pueder ser usada para requerir expl@'{@dotless{i}}citamente que una funci@'on espec@'{@dotless{i}}fica deba ser tratada en l@'{@dotless{i}}nea como sea posible, incluyendo sus usos en otros archivos.@footnote{En este caso, la definici@'on de la funci@'on en l@'{@dotless{i}}nea debe ser hecha en otro archivo (p.e. en un archivo de cabeceras).} El Manual de Referencia de GCC ''@cite{Using GCC}'' suministra un completo detalle de la palabra reservada @code{inline}, y emplea los calificadores @code{static} y @code{extern} para controlar el enlazado de las funciones en l@'{@dotless{i}}nea expl@'{@dotless{i}}citamente (@pxref{Lectura adicional}). @node Dilema velocidad-espacio @section Dilema velocidad-espacio @cindex dilema velocidad-espacio, en optimizaci@'on @cindex optimizaci@'on, dilema velocidad-espacio @cindex dilema, entre velocidad y espacio en optimizaci@'on @cindex espacio versus velocidad, dilema en optimizaci@'on Mientras que algunas formas de optimizaci@'on, tales como la eliminaci@'on de subexpresiones comunes, son capaces simult@'aneamente de incrementar la velocidad y reducir el tama@~no de un programa, otros tipos de optimizaci@'on producen c@'odigo m@'as r@'apido a costa de incrementar el tama@~no del ejecutable. Esta elecci@'on entre velocidad y espacio se denomina @dfn{dilema velocidad-espacio}. Las optimizaciones con el @dfn{dilema velocidad-espacio} se pueden usar en sentido inverso para hacer ejecutables peque@~nos, a cambio de hacerlos correr m@'as lentos. @subsection Desenrollado de bucle @cindex Desenrollado de bucle, optimizaci@'on @cindex optimizaci@'on, desenrollado de bucle @cindex desenrollado, bucles (optimizaci@'on) Un primer ejemplo de optimizaci@'on con el @dfn{dilema velocidad-espacio} es @dfn{Desenrollado de bucle}. Esta forma de optimizaci@'on incrementa la velocidad de los bucles eliminando la condici@'on de terminaci@'on del bucle en cada iteraci@'on. Por ejemplo, el siguiente bucle de 0 a 7 comprueba la condici@'on @code{i < 8} en cada iteraci@'on: @example for (i = 0; i < 8; i++) @{ y[i] = i; @} @end example @noindent Al final del bucle, esta condici@'on ha sido comprobada 9 veces, y gran parte del tiempo de ejecuci@'on fu@'e gastado en la comprobaci@'on. Una forma m@'as eficiente de escribir el mismo c@'odigo es simplemente @dfn{desenrollar el bucle} y ejecuta las instrucciones directamente: @example y[0] = 0; y[1] = 1; y[2] = 2; y[3] = 3; y[4] = 4; y[5] = 5; y[6] = 6; y[7] = 7; @end example @noindent Este tipo de c@'odigo no requiere ning@'un test, y se ejecuta a la m@'axima velocidad. Una vez que cada asignaci@'on es independiente, permite ser compilado para usar procesamiento paralelo cuando es soportado. Desenrollado de bucle es una optimizaci@'on que incrementa la velocidad del ejecutable resultante pero generalmente incrementa su tama@~no (a menos que el bucle sea muy corto, con s@'olo una o dos iteraciones, por ejemplo). Desenrollado de bucle se hace posible cuando el l@'{@dotless{i}}mite superior de un bucle es desconocido, siempre y cuando las condiciones de inicio y terminaci@'on sean manejadas correctamente. Por ejemplo, el mismo bucle con un l@'{@dotless{i}}mite superior arbitrario, @example for (i = 0; i < n; i++) @{ y[i] = i; @} @end example @noindent puede ser reescrito por el compilador como sigue: @example for (i = 0; i < (n % 2); i++) @{ y[i] = i; @} for ( ; i + 1 < n; i += 2) /* sin inicializador */ @{ y[i] = i; y[i+1] = i+1; @} @end example @noindent El primer bucle trata el caso @code{i = 0} cuando @code{n} es impar, y el segundo bucle trata el resto de iteraciones. Observe que el segundo bucle no usa un inicializador en el primer argumento de la instrucci@'on @code{for}, justo contin@'ua donde el primer bucle termin@'o. Las instrucciones del segundo bucle pueden ser paralelizadas, y el total del n@'umero de tests se reduce en un factor de 2 (aproximadamente). Factores mayores se pueden alcanzar desenrollando m@'as instrucciones dentro del bucle, a cambio de agrandar el tama@~no del c@'odigo. @node Planificaci@'on @section Planificaci@'on @cindex planificaci@'on, fase de optimizaci@'on @cindex planificaci@'on de instrucci@'on, optimizaci@'on @cindex segmentaci@'on, explicaci@'on de El menor nivel de optimizaci@'on es la @dfn{planificaci@'on}, en el cual el compilador determina el mejor orden para las instrucciones individuales. La mayor@'{@dotless{i}}a de las CPUs permiten que una o m@'as nuevas instrucciones comiencen a ejecutarse antes de que otras hallan terminado. Muchas CPUs tienen soporte para @dfn{segmentaci@'on}, donde m@'ultiples instrucciones se ejecutan en paralelo en la misma CPU. Cuando la planificaci@'on est@'a habilitada, las instrucciones pueden disponer de sus resultados llegando a tener disponible la siguiente instrucci@'on en el tiempo correcto, y a permitir un m@'aximo de ejecuci@'on en paralelo. La @dfn{planificaci@'on} aumenta la velocidad de un ejecutable sin incrementar su tama@~no, pero requiere memoria y tiempo adicional en sus procesos de compilaci@'on (dada su complejidad). @node Niveles de optimizaci@'on @section Niveles de optimizaci@'on @cindex optimizaci@'on, compilando con @option{-O} @cindex optimizaci@'on, niveles de @cindex niveles de optimizaci@'on @cindex @option{O}, opci@'on para establecer el nivel de optimizaci@'on Para controlar los tiempos de compilaci@'on y el uso de memoria, y la compensaci@'on entre velocidad y espacio para el ejecutable resultante, GCC suministra un rango de niveles generales de optimizaci@'on, numerados desde 0 al 3, as@'{@dotless{i}} como opciones individuales para tipos espec@'{@dotless{i}}ficos de optimizaci@'on. El nivel de optimizaci@'on se elige con la opci@'on @option{-O@var{NIVEL}}, donde @code{@var{NIVEL}} es un n@'umero del 0 al 3. Los efectos de los diferentes niveles de optimizaci@'on se describen a continuaci@'on: @table @asis @item @option{-O0} o @r{sin opci@'on @option{-O}} (por defecto) @cindex @option{-O0}, opci@'on para establece nivel de optimizaci@'on cero @cindex c@'odigo no optimizado (@option{-O0}) Este nivel de optimizaci@'on no realiza ninguna optimizaci@'on y compila el c@'odigo fuente de la forma m@'as sencilla posible. Cada comando en el c@'odigo fuente es convertido directamente a sus correspondientes instrucciones en el archivo ejecutable, sin reorganizaci@'on. Esta es la mejor opci@'on a usar cuando se depura un programa y es la opci@'on por defecto si no se especifica una opci@'on de nivel de optimizaci@'on. @item @option{-O1} @r{o} @option{-O} @cindex @option{-O1}, opci@'on para establecer el nivel de optimizaci@'on uno Este nivel activado es la optimizaci@'on m@'as frecuente ya que no requiere compensar entre velocidad y espacio. Con esta opci@'on los ejecutables resultantes deber@'{@dotless{i}}an ser m@'as peque@~nos y r@'apidos que con la opci@'on @option{-O0}. La optimizaci@'on m@'as costosa, como la planificaci@'on de instrucciones, no es usada a este nivel. Compilar con la opci@'on @option{-O1} puede a menudo tomar menos tiempo que la compilaci@'on con la opci@'on @option{-O0}, debido a la reducida cantidad de datos que necesitan ser procesados despu@'es de una simple optimizaci@'on. @item @option{-O2} @cindex @option{-O2}, opci@'on para establecer el nivel de optimizaci@'on dos @cindex despliegue, opciones para Esta opci@'on activa m@'as optimizaciones, adem@'as de las empleadas por @option{-O1}. Estas optimizaciones adicionales incluyen la planificaci@'on de instrucciones. S@'olo se emplear@'an optimizaciones que no requieren compensanci@'on entre velocidad y espacio, as@'{@dotless{i}} el ejecutable no aumentar@'a de tama@~no. Al compilador le costar@'a m@'as compilar programas y necesitar@'a m@'as memoria que con la opci@'on @option{-O1}. Esta opci@'on es la m@'as elegida en el desarrollo de programas, porque suministra un m@'aximo de optimizaci@'on sin incrementar el tama@~no del ejecutable. Es la opci@'on del nivel de optimizaci@'on por defecto en las versiones de paquetes GNU. @item @option{-O3} @cindex @option{-O3}, opci@'on para establecer el nivel de optimizaci@'on tres Esta opci@'on activa las m@'as costosas optimizaciones, tales como funciones en-l@'{@dotless{i}}nea, adem@'as de todas las optimizaciones de niveles inferiores @option{-O2} y @option{-O1}. El nivel de optimizaci@'on @option{-O3} incrementa la velocidad del ejecutable. Bajo algunas circunstancias donde esta optimizaci@'on no es posible, esta opci@'on podr@'{@dotless{i}}a hacer un programa muy lento. @item @option{-funroll-loops} @cindex @option{-funroll-loops}, opci@'on para hacer optimizaci@'on por desenrollado de bucles @cindex @option{funroll-loops}, opci@'on para hacer optimizaci@'on por desenrollado del bucles @cindex Desenrollado de bucle, optimizaci@'on @cindex optimizaci@'on, desenrollado de bucle @cindex desenrollado, bucles (optimizaci@'on) Esta opci@'on activa el desenrollado de bucles, y es independiente de otras opciones de optimizaci@'on. Se incrementar@'a el tama@~no del ejecutable. Si esta opci@'on produce o no un resultado beneficioso ser@'a comprobado sobre una base caso por caso. @item @option{-Os} @cindex @option{-Os}, opci@'on para hacer optimizaci@'on por tama@~no @cindex optimizaci@'on por tama@~no, opci@'on @option{-Os} @cindex tama@~no, optimizaci@'on por, @option{-Os} Esta opci@'on selecciona las optimizaciones que reducen el tama@~no del ejecutable. El prop@'osito de esta opci@'on es producir el ejecutable menor posible, para sistemas con restricciones de memoria o espacio de disco. En algunos casos un peque@~no ejecutable es m@'as r@'apido, debido al mejor uso de memoria cach@'e. @end table Es importante recordar que el beneficio de altos niveles de optimizaci@'on debe sopesarse contra el coste. El coste de la optimizaci@'on incluye una gran complejidad en depuraci@'on, e incrementa los requerimientos de tiempo y memoria durante la compilaci@'on. Para la mayor@'{@dotless{i}}a de los prop@'ositos es conveniente usar la opci@'on @option{-O0} para depuraci@'on, y la opci@'on @option{-O2} para el desarrollo y uso posterior. @node Ejemplos de optimizaci@'on @section Ejemplos @cindex optimizaci@'on, ejemplo de El siguiente programa ser@'a usado para demostrar los efectos de los diferentes niveles de optimizaci@'on: @example @verbatiminclude optim.es.c @end example @noindent @cindex benchmarking, con comando @code{time} @cindex comando @code{time}, midiendo tiempo de ejecuci@'on @cindex tiempo de ejecuci@'on, midiendo con comando @code{time} El programa principal contiene un bucle invocando a la funci@'on @code{powern}. Esta funci@'on calcula la en@'esima potencia de un n@'umero en coma flotante con repetici@'on de multiplicaciones ---esto ha sido elegido as@'{@dotless{i}} porque es conveniente para funciones en l@'{@dotless{i}}nea y desenrollado de bucles. El tiempo de ejecuci@'on de un programa puede ser medido usando el comando @code{time} en la GNU Bash shell. Aqu@'{@dotless{i}} se muestran los resultados para el programa anterior, compilado en un 566@dmn{MHz} Intel Celeron con 16@dmn{KB} L1-cache y 128@dmn{KB} L2-cache, usando GCC 3.3.1 en un sistema GNU/Linux: @example $ gcc -Wall -O0 optim.es.c -lm $ time ./a.out real 0m13.388s user 0m13.370s sys 0m0.010s $ gcc -Wall -O1 optim.es.c -lm $ time ./a.out real 0m10.030s user 0m10.030s sys 0m0.000s $ gcc -Wall -O2 optim.es.c -lm $ time ./a.out real 0m8.388s user 0m8.380s sys 0m0.000s $ gcc -Wall -O3 optim.es.c -lm $ time ./a.out real 0m6.742s user 0m6.730s sys 0m0.000s $ gcc -Wall -O3 -funroll-loops optim.es.c -lm $ time ./a.out real 0m5.412s user 0m5.390s sys 0m0.000s @end example @noindent La entrada relevante en la salida para comparar la velocidad de los ejecutables resultantes es el tiempo @samp{user}, el cual da el tiempo de CPU empleado en la ejecuci@'on del proceso actual. En otras filas, @samp{real} y @samp{sys}, registran el tiempo total real de los procesos que se ejecutan (incluyendo los tiempos de otros procesos que est@'an usando la CPU) y el tiempo empleado en esperar las llamadas al sistema operativo. Aunque s@'olo se ha mostrado una ejecuci@'on, las pruebas de rendimiento ser@'an ejecutadas varias veces para confirmar los resultados. En los resultados puede apreciarse en este caso que incrementando el nivel de optimizaci@'on con @option{-O1}, @option{-O2} y @option{-O3} se produce un incremento de la velocidad. A@~nadiendo la opci@'on @option{-funroll-loops} se produce la mayor rapidez. La velocidad del programa aumenta al doble de la inicial, cuando va desde el c@'odigo no optimizado al m@'as alto nivel de optimizaci@'on. Observe que un peque@~no programa como este puede tener considerables variaciones para versiones de sistemas y compiladores. Por ejemplo, en un sistema Mobile 2.0@dmn{GHz} Intel Pentium 4M la tendencia del resultado usando la misma versi@'on de GCC es similar excepto que el rendimiento con @option{-O2} es ligeramente peor que con @option{-O1}. Esto ilustra un importante punto: las optimizaciones no necesariamente hacen programas m@'as r@'apidos en todos los casos. @node Optimizaci@'on y depuraci@'on @section Optimizaci@'on y depuraci@'on @cindex depurando, con optimizaci@'on @cindex optmizaci@'on, con depuraci@'on Con GCC es posible usar optimizaci@'on en combinaci@'on con la opci@'on @option{-g} de depuraci@'on. Otros muchos compiladores no permiten esto. Cuando se usa depuraci@'on y optimizaci@'on juntas, la reorganizaci@'on interna llevada a cabo por el optimizador puede hacer dif@'{@dotless{i}}cil ver que est@'a haciendo un programa cuando se examinan programas optimizados con el depurador. Por ejemplo, las variables temporales son a menudo eliminadas, y el orden de las instrucciones puede estar cambiado. @cindex despliegue, opciones para Sin embargo, cuando un programa falla inesperadamente, cualquier informaci@'on de depuraci@'on es mejor que nada ---as@'{@dotless{i}} el uso de @option{-g} se recomienda para programas optimizados, tanto para desarrollo como para mantenimiento. La opci@'on @option{-g} de depuraci@'on est@'a habilitada por defecto en las versiones de los paquetes GNU, junto con la opci@'on @option{-O2} de optimizaci@'on. @node Optimizaci@'on y avisos del compilador @section Optimizaci@'on y avisos del compilador @cindex optimizaci@'on, y avisos del compilador @cindex avisos, y optimizaci@'on Cuando la optimizaci@'on est@'a activa, GCC puede producir avisos adicionales que no aparecen cuando se compila sin optimizaci@'on. @cindex an@'alisis de flujo de datos Como parte del proceso de optimizaci@'on, el compilador examina el uso de todas las variables y sus valores iniciales ---esto es llamado un @dfn{an@'alisis de flujo de datos}. @'Esto forma la base de otras estrategias de optimizaci@'on, tales como la planificaci@'on de instrucciones. El efecto del an@'alisis del flujo de datos es que el compilador puede detectar el uso de variables indefinidas. @cindex @option{-Wuninitialized}, opci@'on de aviso de variables no inicializadas @cindex @option{Wuninitialized}, opci@'on de aviso de variables no inicializadas La opci@'on @option{-Wuninitialized} (la cual est@'a incluida en @option{Wall}) avisa sobre variables que son leidas sin haber sido inicializadas. S@'olo funciona cuando el programa es compilado con optimizaci@'on, de modo que el an@'alisis del flujo de datos est@'a habilitado. La siguiente funci@'on contiene un ejemplo con tales variables: @example @verbatiminclude uninit.es.c @end example @noindent @cindex C/C++, riesgos de uso Esta funci@'on funciona correctamente para la mayor@'{@dotless{i}}a de argumentos, pero tiene un fallo cuando @code{x} es cero ---en este caso el valor de retorno de la variable @code{s} ser@'a indefinido. Compilando el programa con la opci@'on @option{-Wall} solamente no produce ning@'un aviso, porque el an@'alisis del flujo de datos no es llevado a cabo sin optimizaci@'on: @example $ gcc -Wall -c uninit.es.c @end example @noindent Para producir avisos, el programa debe ser compilado con @option{-Wall} y optimizaci@'on simult@'aneamente. En la pr@'actica, el nivel de optimizaci@'on @option{-O2} es necesario para obtener buenos avisos: @cindex variable no inicializada, aviso de @cindex variable, aviso de uso sin inicializar @example $ gcc -Wall -O2 -c uninit.c uninit.c: In function 'sign': uninit.c:11:3: warning: 's' may be used uninitialized in this function [-Wuninitialized] @end example @noindent Esto detecta correctamente la posibilidad de que la variable @code{s} sea empleada sin haber sido definida. Observe que mientras GCC habitualmente encontrar@'a la mayor@'{@dotless{i}}a de las variables no inicializadas, se estar@'an usando heur@'{@dotless{i}}sticas que ocasionalmente fallar@'an en algunos casos complicados y otras veces falseando avisos. En esta @'ultima situaci@'on, es a menudo posible reescribir las l@'{@dotless{i}}neas relevantes de una forma sencilla que elimine los avisos y mejore la legibilidad del c@'odigo fuente. @node Compilando un programa C++ @chapter Compilando un programa C++ @cindex C++, @code{g++} ejemplo de un compilador verdadero @cindex traductores, desde C++ a C, comparados con @code{g++} Este cap@'{@dotless{i}}tulo describe el uso de GCC para compilar programas escritos en C++. y las opciones espec@'{@dotless{i}}ficas de l@'{@dotless{i}}nea de comandos para este lenguaje. El compilador GNU C++ suministrado por GCC es un verdadero compilador de C++ ---compila c@'odigo fuente directamente en lenguaje ensamblador. Otros ``compiladores'' C++ hacen la traducci@'on convirtiendo los programas C++ en programas C, y compilan el programa C resultante usando el compilador existente. Un verdadero compilador C++, tal como GCC, es capaz de proveer mejor soporte para informar los errores, depuraci@'on y optimizaci@'on. @menu * Compilando un peque@~no programa C++:: * Opciones de compilaci@'on en C++:: * Usando la librer@'{@dotless{i}}a est@'andar de C++:: * Plantillas:: @end menu @node Compilando un peque@~no programa C++ @section Compilando un peque@~no programa C++ @cindex C++, compilando un peque@~o programa con @code{g++} @cindex @code{g++}, compilando programas C++ @cindex compilando programas C++ con @code{g++} @cindex programa C++ simple, compilando El procedimiento para compilar un programa C++ es el mismo que para un programa C, pero usa el comando @code{g++} en vez de @code{gcc}. Ambos compiladores son parte de la colecci@'on de compiladores GNU. @cindex Hola Mundo, programa en C++ Para mostrar el uso de @code{g++}, aqu@'{@dotless{i}} est@'a la versi@'on del programa @dfn{Hola Mundo} escrita en C++: @example @verbatiminclude hola.es.cc @end example @noindent El programa puede ser compilado con la siguiente l@'{@dotless{i}}nea de comando: @example $ g++ -Wall hola.es.cc -o hola@end example @noindent @cindex @code{.cc}, extensi@'on de fichero C++ @cindex @code{cc}, extensi@'on de fichero C++ @cindex @code{.cpp}, extensi@'on de fichero C++ @cindex @code{cpp}, extensi@'on de fichero C++ @cindex @code{.cxx}, extensi@'on de fichero C++ @cindex @code{cxx}, extensi@'on de fichero C++ @cindex extensi@'on, @code{.C}, fichero C++ @cindex extensi@'on, @code{.cc}, fichero C++ @cindex extensi@'on, @code{.cpp}, fichero C++ @cindex extensi@'on, @code{.cxx}, fichero C++ @cindex extensi@'on, @code{.C}, fichero C++ @cindex file extension, @code{.C}, fichero C++ @cindex file extension, @code{.cc}, fichero C++ @cindex file extension, @code{.cpp}, fichero C++ @cindex file extension, @code{.cxx}, fichero C++ @cindex file extension, @code{.C}, fichero C++ @cindex C++, extensiones de fichero El frontend C++ de GCC usa muchas opciones similares al compilador de C @code{gcc}. Adem@'as, soporta opciones adicionales para controlar las caracter@'{@dotless{i}}sticas del lenguaje C++, las cuales ser@'an descritas en este cap@'{@dotless{i}}tulo. Observe que el c@'odigo fuente C++ debe darse en una de las extensiones v@'alidas para archivos C++ @file{.cc}, @file{.cpp}, @file{cxx} o @file{.C} en vez de la extensi@'on @file{.c} usada por programas C. @cindex @option{-ansi}, opci@'on usada con @code{g++} @cindex @option{ansi}, opci@'on usada con @code{g++} @cindex ISO C++, controlado con opci@'on @option{-ansi} @cindex ejecutando un fichero ejecutable, C++ El ejecutable resultante puede ser ejecutado de la misma forma que la versi@'on C, simplemente tecleando su nombre: @example $ ./hola @exclamdown{}Hola, mundo! @end example @noindent El ejecutable produce la misma salida que la versi@'on C del programa usando @code{std::cout} en vez de la funci@'on C @code{printf}. Todas las opciones usadas en comandos @code{gcc} en cap@'{@dotless{i}}tulos anteriores pueden aplicarse a @code{g++} sin cambios, al igual que los procedimientos para compilar y enlazar archivos y librer@'{@dotless{i}}as (usando @code{g++} en vez de @code{gcc}, por supuesto). Una natural diferencia es que la opci@'on @option{-ansi} requiere conformidad con el est@'andar C++, en vez de con el est@'andar C, cuando es usado con @code{g++}. Observe que los programas que usan archivos objeto C++ deben ser enlazados con @code{g++}, con objeto de suministrar las librer@'{@dotless{i}}as necesarias. Intentar enlazar un archivo objeto C++ con el compilador de C @code{gcc} causar@'a errores del tipo ``undefined reference'' para las funciones de la librer@'{@dotless{i}}a est@'andar de C++: @cindex referencia indefinida a funci@'on en C++, ocurre enlazando con @code{gcc} @example $ g++ -Wall -c hola.es.cc $ gcc hola.o @r{(deber@'{@dotless{i}}a usar @code{g++})} hola.o: In function `main': hola.o(.text+0x1b): undefined reference to `std::cout' ..... hola.o(.eh_frame+0x11): undefined reference to `__gxx_personality_v0'@end example @noindent Las referencias indefinidas a funciones internas de librer@'{@dotless{i}}as en tiempo de ejecuci@'on, tales como @code{__gxx_personality_v0}, son pruebas del enlazado de archivos objetos C++ con @code{gcc} en vez de con @code{g++}.@footnote{Puesto que estas funciones son internas, el error mostrado en este ejemplo ser@'a diferente en otras versiones del compilador.} Enlazando el mismo archivo objeto con @code{g++} suministra todas las librer@'{@dotless{i}}as C++ necesarias y produce un ejecutable que funciona: @example $ g++ hola.es.o $ ./a.out @exclamdown{}Hola, mundo!@end example @noindent @cindex @code{__gxx_personality_v0}, error de referencia indefinida @cindex @code{gxx_personality_v0}, error de referencia indefinida @cindex @code{gcc}, usado inconsistentemente con @code{g++} @cindex error de referencia indefinida para @code{__gxx_personality_v0} Un aspecto que algunas veces causa confusi@'on es que @code{gcc} actualmente compila c@'odigo fuente C++ cuando detecta la extensi@'on de archivos C++, pero no puede enlazar el archivo objeto resultante. @example $ gcc -Wall -c hola.es.cc @r{(correcto, en vez de C++)} $ gcc hola.o hola.o: In function `main': hola.o(.text+0x1b): undefined reference to `std::cout'@end example @noindent Para eliminar este problema, use @code{g++} consistentemente para programas C++ y @code{gcc} para programas C. @node Opciones de compilaci@'on en C++ @section Opciones de compilaci@'on en C++ La mayor@'{@dotless{i}}a de las opciones pueden ser usadas tanto para programas C como C++, pero adem@'as hay unas pocas opciones que son espec@'{@dotless{i}}ficas de cada lenguaje. Esta secci@'on describe algunas de las opciones adicionales, y las mejoras de las opciones existentes, que est@'an disponibles en @command{g++}. @table @asis @item @option{-Wall} y @option{-W} Cuando se compila con @code{g++}, las opciones @option{-Wall} y @option{-W} incluyen avisos extras espec@'{@dotless{i}}ficos de C++ (los avisos relacionan las funciones miembro con las clases virtuales). El uso de estas opciones es siempre recomendado mientras se depura un programa. @item @option{-fno-default-inline} @cindex @option{-fno-default-inline}, opci@'on @cindex @option{fno-default-inline}, opci@'on @cindex @option{no-default-inline}, opci@'on Esta opci@'on deshabilita el inlining por defecto de las funciones miembro definidas en los cuerpos de las clases C++. GCC normalmente inlines todas las funciones posibles cuando la optimizaci@'on est@'a activada, incluso si no se us@'o expl@'{@dotless{i}}citamente la palabra reservada @code{inline}. Elija esta opci@'on si desea controlar el inlining por s@'{@dotless{i}} mismo, o si desea poner un punto de ruptura en una funci@'on miembro que en otro caso ser@'{@dotless{i}}a inlined (ya que no es posible poner un punto de ruptura en una funci@'on inlined). @item @option{-Weffc++} @cindex @option{-Weffc++}, opci@'on @cindex @option{Weffc++}, opci@'on @cindex opci@'on de aviso @option{effc++} Esta opci@'on avisa sobre el c@'odigo C++ que rompe alguna de las directrices dadas en los libros ``@cite{Effective C++}'' y ``@cite{More Effective C++} de Scott Meyers. Por ejemplo, se mostrar@'a un aviso si una clase usa memoria din@'amicamente ubicada si no es definida como copia de un constructor y un operador de asignaci@'on. Observe que los archivos cabeceras de las librer@'{@dotless{i}}as est@'andar no siguen estas directrices, as@'{@dotless{i}} se puede usar esta opci@'on para un test ocasional de posibles problemas en su propio c@'odigo en vez de compilar con ella todo el tiempo. @item @option{-Wold-style-cast} @cindex @option{-Wold-style-cast} option @cindex @option{Wold-style-cast}, opci@'on @cindex opci@'on de aviso @option{old-style-cast} Esta opci@'on destaca cualquier uso de moldes con el estilo de C en programas C++. El lenguaje C++ facilita las palabras reservadas @code{static_cast}, @code{dynamic_cast}, @code{reinterpret_cast} y @code{const_cast} para manejar moldes y @'estos con preferidos a menudo (aunque los moldes al estilo C son permitidos). @end table @node Usando la librer@'{@dotless{i}}a est@'andar de C++ @section Usando la librer@'{@dotless{i}}a est@'andar de C++ @cindex C++, librar@'{@dotless{i}}a est@'andar @cindex librer@'{@dotless{i}}a est@'andar, C++ @cindex librer@'{@dotless{i}}a, librar@'{@dotless{i}}a est@'andar C++ Una implementaci@'on de la librer@'{@dotless{i}}a est@'andar de C++ es suministrada como parte de GCC. El siguiente programa usa la clase @code{string} de la librar@'{@dotless{i}}a est@'andar para reimplementar el programa @dfn{Hola Mundo}: @example @verbatiminclude holastr.es.cc @end example @noindent El programa puede ser compilado y ejecutado usando los comandos siguientes: @example $ g++ -Wall holastr.es.cc $./a.out @exclamdown{}Hola, Mundo!@end example @noindent @cindex C++, espacio de nombres @code{std} @cindex espacio de nombres @code{std} en C++ @cindex @code{std} espacio de nombres en C++ @cindex archivo de cabecera, sin extensi@'on @code{.h} para C++ Observe que de acuerdo con el est@'andar C++, los archivos cabeceras de las librer@'{@dotless{i}}as C++ mismas no usan una extensi@'on de archivo. Las clases en la librer@'{@dotless{i}}a son adem@'as definidas dentro del espacio de nombres @code{std}, as@'{@dotless{i}} la directiva @code{using namespace std} es necesaria para acceder a ellas, a menos que el prefijo @code{std::} sea usado en todas partes (como en la secci@'on anterior). @node Plantillas @section Plantillas @cindex plantillas, en C++ @cindex programaci@'on gen@'erica, en C++ @cindex C++, plantillas Las plantillas facilitan la posibilidad de definir clases C++ que soporten t@'ecnicas @dfn{gen@'ericas de programaci@'on}. Las plantillas se pueden considerar como una clase poderosa de macro. Cuando una plantilla de clase o funci@'on es usada con una clase o tipo espec@'{@dotless{i}}fico, tal como @code{float} o @code{int}, el c@'odigo correspondiente a la plantilla es compilado con el tipo sustituido en los lugares apropiados. @menu * Usando plantillas de librer@'{@dotless{i}}as est@'andar de C++:: * Proporcionando sus propias plantillas:: * Instanciaci@'on expl@'{@dotless{i}}cita de plantillas:: * La palabra reservada export:: @end menu @node Usando plantillas de librer@'{@dotless{i}}as est@'andar de C++ @subsection Usando plantillas de librer@'{@dotless{i}}as est@'andar de C++ @cindex Standard Template Library (STL) @cindex C++, librar@'{@dotless{i}}a est@'andar de plantillas La librer@'{@dotless{i}}a est@'andar @file{libstdc++} facilitada con GCC suministra un amplio rango de contenedores de clases gen@'ericas, tales como listas y colas, en adici@'on a algoritmos generales tales como ordenaci@'on. Estas clases fueron originalmente parte de la Standard Template Library (STL), la cual era un paquete separado, pero no est@'a incluida en la misma librer@'{@dotless{i}}a est@'andar C++. El siguiente programa demuestra el uso de una librar@'{@dotless{i}}a de plantillas creando una lista de cadenas con la plantilla @code{list}: @example @verbatiminclude string.es.cc @end example @noindent No son necesarias opciones especiales para usar las plantillas de clases de las librer@'{@dotless{i}}as est@'andar; las opciones de la l@'{@dotless{i}}nea de comandos para compilar este programa son las mismas de antes: @example $ g++ -Wall string.es.cc $ ./a.out # items = 2@end example @noindent @cindex C++, librar@'{@dotless{i}}a est@'andar @cindex @code{libstdc++}, librer@'{@dotless{i}}a est@'andar C++ Observe que el ejecutable creado por @code{g++} usando la librer@'{@dotless{i}}a est@'andar de C++ enlazar@'a a la librer@'{@dotless{i}}a compartida @file{libstdc++}, la cual es suministrada como parte de la instalaci@'on por defecto de GCC. Hay varias versiones de esta librer@'{@dotless{i}}a ---si distribuye ejecutables usando la librer@'{@dotless{i}}a est@'andar de C++ necesita asegurar que los destinatarios tienen una versi@'on compatible de @file{libstdc++}, o enlazar su programa est@'aticamente usando la opci@'on de l@'{@dotless{i}}nea de comandos @option{-static}. @node Proporcionando sus propias plantillas @subsection Proporcionando sus propias plantillas @cindex instanciaci@'on, de plantillas en C++ @cindex C++, instanciaci@'on de plantillas @cindex modelo de compilaci@'on de inclusi@'on, en C++ @cindex compilaci@'on, modelo para plantillas @cindex plantillas, modelo de compilaci@'on de inclusi@'on Adem@'as de las plantillas de clases suministradas por la librer@'{@dotless{i}}a est@'andar de C++ puede definir sus propias librer@'{@dotless{i}}as. La forma recomendada de usar plantillas con @code{g++} es siguiendo el @dfn{modelo de compilaci@'on de inclusi@'on}, donde las definiciones de plantillas est@'an puestas en los archivos de cabeceras. Este es el m@'etodo usado por la librer@'{@dotless{i}}a est@'andar de C++ suministrada con el mismo GCC. Los archivos de cabeceras pueden ser incluidos con @samp{#include} en cada archivo fuente donde se necesite. @cindex buffer circular, plantilla de ejemplo @cindex buffer, plantilla de ejemplo Por ejemplo, el siguiente archivo de plantilla crea una simple clase @code{Buffer} que representar@'a un buffer circular tratando objetos del tipo @code{T}. @example @verbatiminclude buffer.es.h @end example @noindent @cindex guardas include, en archivo de cabecera @cindex archivo de cabecera, con guardas include El archivo contiene tanto la declaraci@'on de la clase como la definici@'on de las funciones miembro. Esta clase s@'olo se muestra con prop@'ositos de demostraci@'on y no debe ser considerada un ejemplo de buena programaci@'on. Obs@'ervese el uso de @dfn{guardas include}, que comprueban la existencia de una macro @w{@code{BUFFER_H}}, asegurando que la definici@'on en el archivo de cabecera ser@'a s@'olo considerada una vez si el archivo es incluido m@'ultiples veces en el mismo contexto. El programa siguiente emplea la plantilla de clase @code{Buffer} para crear un buffer de tama@~no 10, almacenando los valores en coma flotante @math{0.25} y @math{1.25} en el buffer: @example @verbatiminclude tprog.es.cc @end example @noindent Las definiciones de la clase de plantilla y sus funciones est@'an incluidas en el archivo fuente del programa con @samp{#include "buffer.es.h"} antes de ser usada. El programa puede entonces ser compilado usando la siguiente l@'{@dotless{i}}nea de comandos: @example $ g++ -Wall tprog.es.cc $ ./a.out valor almacenado = 1.25@end example @noindent En el momento en que las funciones de la plantilla son usadas en el c@'odigo fuente, @code{g++} compila las definiciones apropiadas de los archivos de cabeceras y pone las funciones compiladas en el correspondiente archivo objeto. @cindex error de definici@'on m@'ultiple de s@'{@dotless{i}}mbolo, con C++ @cindex enlazador, GNU comparado con otros enlazadores Si una plantilla de funci@'on es usada varias veces en un mismo programa ser@'a almacenada en m@'as de un archivo objeto. El enlazador GNU asegura que s@'olo una copia ser@'a puesta en el ejecutable final. Otros enlazadores pueden devolver errores tipo ``@dfn{definici@'on m@'ultiple de s@'{@dotless{i}}mbolo}'' cuando aparecen m@'as de una copia de una plantilla de funci@'on ---un m@'etodo de trabajo con estos enlazadores es descrito m@'as adelante. @node Instanciaci@'on expl@'{@dotless{i}}cita de plantillas @subsection Instanciaci@'on expl@'{@dotless{i}}cita de plantillas @cindex plantillas, instanciaci@'on espl@'{@dotless{i}}cita @cindex instanciaci@'on, expl@'{@dotless{i}}cita versus impl@'{@dotless{i}}cita en C++ @cindex instanciaci@'on expl@'{@dotless{i}}cita de plantillas @cindex @option{-fno-implicit-templates}, opci@'on para deshabilitar la instanciaci@'on de plantillas @cindex @option{fno-implicit-templates}, opci@'on para deshabilitar la instanciaci@'on de plantillas Para tomar un completo control sobre la compilaci@'on de plantillas con @code{g++} es posible que se requiera una instanciaci@'on expl@'{@dotless{i}}cita de cada ocurrencia de la plantilla, usando la opci@'on @option{-fno-implicit-templates}. Este m@'etodo no se necesita usando el enlazador GNU ---es un alternativa suministrada para sistemas con enlazadores que no pueden eliminar las definiciones duplicadas de funciones de plantillas en los archivos objetos. Con este enfoque, las funciones de plantillas no son compiladas hasta el momento donde ser@'an usadas, como resultado de la opci@'on @option{-fno-implicit-templates}. En cambio, el compilador busca una instanciaci@'on expl@'{@dotless{i}}cita de la plantilla usando la palabra reservada @code{template} con el tipo espec@'{@dotless{i}}fico para forzar su compilaci@'on (esto es una extensi@'on de GCC del comportamiento est@'andar). Estas instanciaciones son normalmente puestas en archivos fuente separados, los cuales ser@'an compilados para hacer los archivos objetos que contengan todas las funciones de plantillas requeridas por el programa. Esto garantiza que cada plantilla aparezca en un @'unico archivo objeto, y que sea compatible con enlazadores que no puedan eliminar definiciones duplicadas en archivos objeto. Por ejemplo, el siguiente archivo @file{templates.es.cc} contiene una instanciaci@'on expl@'{@dotless{i}}cita de la clase @code{Buffer} usada por el programa @code{tprog.es.cc} mostrado antes: @example @verbatiminclude templates.es.cc @end example @noindent El programa completo puede compilarse y enlazarse usando instanciaci@'on expl@'{@dotless{i}}cita con el siguiente comando: @example $ g++ -Wall -fno-implicit-templates -c tprog.es.cc $ g++ -Wall -fno-implicit-templates -c templates.es.cc $ g++ tprog.o templates.o $ ./a.out valor almacenado = 1.25@end example @noindent El c@'odigo objeto de todas las funciones de plantillas est@'a contenido en el archivo @code{templates.o}. No hay c@'odigo objeto para la funci@'on de plantilla en @file{tprog.o} cuando este es compilado con la opci@'on @option{-fno-implicit-templates}. Si el programa es modificado para usar tipos adicionales, entonces podr@'{@dotless{i}}an a@~nadirse posteriores instanciaciones expl@'{@dotless{i}}citas en el archivo @file{templates.es.cc}. Por ejemplo, el siguiente c@'odigo a@~nade instanciaciones de objetos Buffer conteniendo valores @code{float}, @code{double} e @code{int}: @example @verbatiminclude templates2.es.cc @end example @noindent @cindex C++, creando librer@'{@dotless{i}}as con instanciaci@'on expl@'{@dotless{i}}cita @cindex librer@'{@dotless{i}}as, creando con instanciaci@'on expl@'{@dotless{i}}cita en C++ La desventaja de la instanciaci@'on expl@'{@dotless{i}}cita es que es necesario conocer qu@'e tipos de plantillas son necesarias en un programa. Para un programa complicado puede ser dif@'{@dotless{i}}cil saberlo por adelantado. Cualquier instanciaci@'on de plantilla perdida ser@'a detectada en tiempo de enlazado, sin embargo, y a@~nadida a la lista de instanciaciones expl@'{@dotless{i}}citas, anotando qu@'e funciones est@'an indefinidas. La instanciaci@'on expl@'{@dotless{i}}cita puede ser empleada para hacer librer@'{@dotless{i}}as de funciones de plantillas precompiladas, creando un archivo objeto que contenga todas las instanciaciones de una funci@'on de plantilla (como en el archivo @file{templates.es.cc} anterior). Por ejemplo, el archivo objeto creado desde la instanciaci@'on de plantilla anterior contiene el c@'odigo m@'aquina necesario para las clases Buffer con tipos @samp{float}, @samp{double} e @samp{int}, y puede ser distribuida como una librer@'{@dotless{i}}a. @node La palabra reservada export @subsection La palabra reservada @code{export} @cindex palabra reservada @code{export}, no soportada en GCC @cindex plantillas, palabra reservada @code{export} En el momento de escribir este libro, GCC no soportaba la nueva palabra reservada C++ @code{export}. Esta palabra reservada era propuesta como una forma de separar la interfaz con las plantillas de su implementaci@'on. Sin embargo a@~nadi@'o complejidad al proceso de enlazado, lo cual en la pr@'actica podr@'{@dotless{i}}a quitar m@'eritos a cualquier ventaja. La palabra reservada @code{export} no es ampliamente usada, y la mayor@'{@dotless{i}}a de los compiladores ni la soportan. El modelo de compilaci@'nn de inclusi@'on descrito anteriormente es recomendado como el m@'as simple y la forma m@'as portable de usar plantillas. @node Opciones espec@'{@dotless{i}}ficas de plataforma @chapter Opciones espec@'{@dotless{i}}ficas de plataforma @cindex opciones espec@'{@dotless{i}}ficas de la plataforma @cindex opciones espec@'{@dotless{i}}ficas de la m@'aquina @cindex opciones, espec@'{@dotless{i}}ficas de la plataforma @cindex @option{-m}, opci@'on de configuraci@'on espec@'{@dotless{i}}ficas de la plataforma @cindex @option{m}, opci@'on de configuraci@'on espec@'{@dotless{i}}fica de la plataforma GCC proporciona un rango de opciones espec@'{@dotless{i}}ficas de la plataforma para los diferentes tipos de CPUs. Estas opciones controlan las caracter@'{@dotless{i}}sticas tales como los modos en coma flotante del hardware, y el uso de instrucciones especiales para diferentes CPUs. Estas pueden seleccionarse con la opci@'on @option{-m} en la l@'{@dotless{i}}nea de comandos, y funciona con todos los frontends de lenguajes GCC, tales como @code{gcc} y @code{g++}. La siguiente secci@'on describe algunas de las opciones disponibles para las plataformas m@'as comunes. Un listado completo de todas las opciones espec@'{@dotless{i}}ficas de la plataforma se puede encontrar en el Manual de Referencia GCC, ``@cite{Using GCC}'' (@pxref{Lectura adicional}). Soporte a nuevos procesadores es a@~nadido a GCC tan pronto como @'este est@'e disponible, por eso algunas de las opciones descritas en este cap@'{@dotless{i}}tulo no se encuentran en anteriores versiones de GCC. @menu * Opciones para Intel y AMD x86:: * Opciones para DEC Alpha:: * Opciones para SPARC:: * Opciones para POWER/PowerPC:: * Soporte de m@'ultiples arquitecturas:: * Usos de coma flotante:: * Portabilidad de los tipos con signo y sin signo:: @end menu @node Opciones para Intel y AMD x86 @section Opciones para Intel y AMD x86 @cindex Intel x86, opciones espec@'{@dotless{i}}ficas de la plataforma @cindex AMD x86, opciones espec@'{@dotless{i}}ficas de la plataforma @cindex x86, opciones espec@'{@dotless{i}}ficas de la plataforma Las caracter@'{@dotless{i}}sticas m@'as usadas de las familias de procesadores Intel y AMD x86 (386, 486, Pentium, etc) pueden ser controladas con opciones espec@'{@dotless{i}}ficas de la plataforma. En estas plataformas, GCC produce c@'odigo ejecutable que es compatible por defecto con todos los procesadores de la familia x86 ---llegando a retroceder hasta el 386. Sin embargo, es posible compilar para un procesador espec@'{@dotless{i}}fico para obtener mejores rendimientos. @cindex Pentium, opciones espec@'{@dotless{i}}ficas de la plataforma @cindex Athlon, opciones espec@'{@dotless{i}}fias de la plataforma Por ejemplo, las versiones recientes de GCC tienen soporte espec@'{@dotless{i}}fico para los m@'as nuevos procesadores tales como Pentium 4 y Athlon AMD. Estos pueden ser seleccionados para Pentium 4 con la siguiente opci@'on: @example $ gcc -Wall -march=pentium4 hola.es.c@end example @noindent @cindex @option{-march}, opci@'on para compilaci@'on para una CPU espec@'{@dotless{i}}fica @cindex @option{m}, opci@'on para compilaci@'on para una CPU espec@'{@dotless{i}}fica y para el Athlon: @example $ gcc -Wall -march=athlon hola.es.c@end example @noindent Un listado completo de los tipos de CPUs soportados se puede encontrar en el Manual de Referencia GCC. El c@'odigo producido con una opci@'on @option{-march=@var{CPU}} espec@'{@dotless{i}}fica puede ser m@'as r@'apido pero no se ejecutar@'a en otros procesadores de la familia x86. Si planea distribuir archivos ejecutables para uso general en procesadores Intel o AMD, @'estos deber@'{@dotless{i}}an ser compilados sin ninguna opci@'on @option{-march}. @cindex @option{-mtune}, opci@'on @cindex @option{mtune}, opci@'on @cindex @option{tune}, opci@'on para una m@'aquina espec@'{@dotless{i}}fica Como alternativa, la opci@'on @option{-mcpu=@var{CPU}} proporciona un compromiso entre velocidad y portabilidad ---se genera c@'odigo que ser@'a afinado para un procesador espec@'{@dotless{i}}fico, en t@'erminos de planificaci@'on de instrucciones, pero no emplea ninguna instrucci@'on que no est@'e disponible en otras CPUs de la faimlia x86.@footnote{En versiones recientes de GCC esta opci@'on ha sido renombrada a @option{-mtune}. La antigua forma @option{-mcpu} continuar@'a funcionando.} El c@'odigo resultante ser@'a compatible con todas las CPUs, y tiene una velocidad ventajosa en la CPU especificada por @option{-mcpu}. Los ejecutables generados con @option{-mcpu} no pueden lograr el mismo rendimiento que con @option{-march}, pero en la pr@'actica puede ser m@'as conveniente. @menu * Extensiones x86:: * Procesadores x86 de 64 bits :: @end menu @node Extensiones x86 @subsection Extensiones x86 @cindex extensiones SSE @cindex extensiones MMX @cindex error de instrucci@'on ilegal @cindex @option{-msse} y opciones relacionadas @cindex @option{msse} y opciones relacionadas GCC puede obtener ventajas de las instrucciones adicionales en las extenciones MMX, SSE, SSE2, SSE3 y 3dnow de los recientes procesadores Intel y AMD. Las opciones @option{-mmmx}, @option{-msse}, @option{-msse2}, @option{-mss3} y @option{-m3dnow} permiten usar instrucciones extra, permitiendo que m@'ultiples palabras de datos sean procesadas en paralelo. Los ejecutables resultantes s@'olo funcionar@'an en procesadores que soporten la apropiada extensi@'on ---en otros sistemas pueden fallar con un error @code{Illegal instruction} o similar.@footnote{En sistemas GNU/Linux, el comando @code{cat /proc/cpuinfo} mostrar@'a informaci@'on de la CPU.} @cindex aritm@'etica en coma flotante, con extensiones SSE @cindex @option{-mfpmath}, opci@'on para aritm@'etica en coma flotante @cindex @option{mfpmath}, opci@'on para aritm@'etica en coma flotante @cindex @option{fpmath}, opci@'on para aritm@'etica en coma flotante La opci@'on @option{-mfpmath=sse} instruye a GCC para usar las extensiones SSE para aritm@'etica en coma flotante cuando sea posible. Para que esta opci@'on tenga efecto, las extensiones SSE o SSE2 deber@'{@dotless{i}}an primero estar habilitadas con @option{-msse} o @option{-msse2}. Observe que el conjunto de extensiones SSE s@'olo soporta operaciones de simple precisi@'on ---la aritm@'etica de doble precisi@'on es parte de SSE2. Desde que la mayor@'{@dotless{i}}a de programas C y C++ declaran las variables en coma flotante como @code{double} en vez de como @code{float}, las opciones combinadas @code{-msse2 -mfpmmath=sse} son frecuentemente necesarias. En procesadores de 64 bits estas opciones est@'an disponibles por defecto. @node Procesadores x86 de 64 bits @subsection Procesadores x86 de 64 bits @cindex opciones espec@'{@dotless{i}}ficas para procesador de 64 bits, AMD e Intel @cindex AMD64, opciones espec@'{@dotless{i}}ficas para procesador de 64 bits AMD ha mejorado el conjunto de instrucciones de 32 bits a un conjunto de instruciones de 64 bits denominado x86-64, el cual es implementado en sus procesadores AMD64.@footnote{Intel ha a@~nadido soporte para este conjunto de instrucciones como ``Mejoras Intel 64 bits'' a sus CPUs Xeon.} En sistemas AMD64 GCC genera c@'odigo de 64 bits por defecto. La opci@'on @option{-m32} permite en cambio que sea generado c@'odigo de 32 bits. @cindex @option{-mcmodel}, opci@'on para AMD64 @cindex @option{mcmodel}, opci@'on para AMD64 El procesador dispone de varios modelos de memoria diferentes para ejecutar programas en modo de 64 bits. El modelo por defecto es el modelo de c@'odigo peque@~no, el cual permite c@'odigo y datos de hasta 2@dmn{GB} de tama@~no. En el modelo de c@'odigo medio permite tama@~no ilimitado de datos y puede ser seleccionado con @option{-mcmode=medium}. Tambi@'en hay un modelo de c@'odigo grande, el cual soporta tama@~no ilimitado de c@'odigo adem@'as del tama@~no ilimitado de datos. Este no est@'a actualmente implementado en GCC una vez que el modelo de c@'odigo medio es suficiente para todos los prop@'ositos pr@'acticos ---los ejecutables con tama@~nos superiores a 2@dmn{GB} en la pr@'actica no se encuentran. @cindex zona roja, en AMD64 @cindex modo kernel, en AMD64 Un especial modelo de c@'odigo de kernel @option{-mcmodel=kernel} es facilitado para c@'odigo a nivel de sistema, tales como el kernel Linux. Un importante punto a observar es que por defecto en los AMD64 hay un @'area de 128-bytes de memoria ubicada por debajo del puntero de pila de los datos temporales, referida como ``zona roja'', la cual no es soportada por el kernel Linux. La compilaci@'on del kernel Linux en un AMD64 requiere la opci@'on @option{-mcmmodel=kernel -mno-red-zone}. @node Opciones para DEC Alpha @section Opciones para DEC Alpha @cindex Alpha, opciones espec@'{@dotless{i}}ficas de la plataforma @cindex DEC Alpha, opciones espec@'{@dotless{i}}ficas de la plataforma El procesador DEC Alpha tiene por defecto una configuraci@'on que maximiza el rendimiento de la aritm@'etica en coma flotante y el coste de un soporte completo para las caracter@'{@dotless{i}}sticas de la aritm@'etica del IEEE. @cindex opciones IEEE, en DEC Alpha @cindex @option{-mieee}, opci@'on para soporte de coma flotante en DEC Alpha @cindex @option{mieee}, opci@'on para soporte de coma flotante en DEC Alpha @cindex NaN, no es un n@'umero, en DEC Alpha @cindex Inf, infinito, en DEC Alpha @cindex n@'umeros no normalizados, en DEC Alpha @cindex desbordamiento por defecto, en DEC Alpha @cindex desbordamiento por defecto gradual, en DEC Alpha @cindex desbordamiento por defecto suave, en DEC Alpha @cindex cero, desde el desbordamienbo inferior en DEC Alpha En la configuraci@'on por defecto en un procesador DEC Alpha no est@'a habilitado el soporte para el tratamiento del infinito y gradual desbordamiento por defecto (n@'umeros no normalizados). Las operaciones que producen el valor infinito o desbordamientos por defecto generar@'an excepciones en coma flotante (tambi@'en conocidas como @dfn{traps}), y causar@'an que el programa termine, a menos que el sistema operativo capture y maneje las excepciones (lo cual es, en general, ineficiente). El est@'andar IEEE especifica que estas operaciones deben producir un resultado especial para representar las cantidades en el formato num@'erico del IEEE. En la mayor@'{@dotless{i}}a de los casos el comportamiento del DEC Alpha es aceptable, ya que la mayor@'{@dotless{i}}a de los programas no producen ni el valor infinito ni desbordamientos por defectos. Para aplicaciones que requieran estas caracter@'{@dotless{i}}sticas, GCC facilita la opci@'on @option{-mieee} para habilitar un completo soporte para la aritm@'etica del IEEE. Para demostrar la diferencia entre los dos casos el siguiente programa divide 1 entre 0: @cindex divisi@'on por cero @cindex cero, divisi@'on por @example @verbatiminclude alpha.es.c @end example @noindent En aritm@'etica del IEEE el resultado de 1/0 es @code{inf} (@dfn{Infinito}). Si el programa es compilado para un procesador Alpha con la configuraci@'on por defecto generar@'a una excepci@'on, que terminar@'a el programa: @example $ gcc -Wall alpha.es.c $ ./a.out Floating point exception @r{(en un procesador Alpha)}@end example @noindent @cindex excepci@'on de coma flotante, en Alpha DEC Usando la opci@'on @option{-mieee} se asegura una completa conformidad con el IEEE ---La divisi@'on 1/0 produce correctamente el resultado @code{inf} y el programa continua ejecut@'andose correctamente: @example $ gcc -Wall -mieee alpha.es.c $ ./a.out x/y = inf @end example @noindent Observe que los programas que generan excepciones en coma flotante corren m@'as lentos cuando son compilados con la opci@'on @option{-mieee}, porque las excepciones son manejadas por software en vez de por hardware. @node Opciones para SPARC @section Opciones para SPARC @cindex Sun SPARC, opciones espec@'{@dotless{i}}ficas de la plataforma @cindex SPARC, opciones espec@'{@dotless{i}}ficas de la plataforma @cindex @option{-mcpu}, opci@'on para compilar en una CPU espec@'{@dotless{i}}fica @cindex @option{mcpu}, opci@'on para compilar en una CPU espec@'{@dotless{i}}fica En el rango de procesadores SPARC la opci@'on @option{-mcpu=@var{CPU}} genera c@'odigo espec@'{@dotless{i}}fico del procesador. Las opciones v@'alidas para @code{@var{CPU}} son @code{v7}, @code{v8} (SuperSPARC), @code{Sparclite}, @code{Sparclet} y @code{v9} (UltraSPARC). El c@'odigo producido con una opci@'on espec@'{@dotless{i}}fica no ejecutar@'a en otros procesadores de la familia SPARC, excepto cuando exista una compatibilidad hacia atr@'as en el mismo procesador. @cindex UltraSPARC, modo 32 bits versus modo 64 bits @cindex tama@~no de palabra, en UltraSPARC @cindex bits, 32 versus 64 en UltraSPARC @cindex @option{-m32} y @option{-m64}, opciones para compilar en entornos de 32 o 64 bits @cindex @option{m32} y @option{m64}, opciones para compilar en entornos de 32 o 64 bits En sistemas UltraSPARC de 64 bits las opciones @option{-m32} y @option{-m64} controlan la generaci@'on de c@'odigo para entornos de 32 @'o 64 bits. El entorno de 32 bits seleccionado por @option{-m32} usa @code{int}, @code{long} y tipos de puntero con un tama@~no de 32 bits. El entorno de 64 bits seleccionado con @option{-m64} usa un tipo @code{int} de 32 bits y @code{long} y tipos de puntero de 64 bits. @node Opciones para POWER/PowerPC @section Opciones para POWER/PowerPC @cindex PowerPC y POWER, opciones espec@'{@dotless{i}}ficas de la plataforma @cindex AIX, opciones espec@'{@dotless{i}}ficas de la plataforma En sistemas que usan la familia de procesadores POWER/PowerPC la opci@'on @option{-mcpu=@var{CPU}} selecciona la generaci@'on de c@'odigo espec@'{@dotless{i}}fico para los modelos de CPU. Los posibles valores de @code{@var{CPU}} incluyen @samp{power}, @samp{power2}, @samp{powerpc}, @samp{powerpc64} y @samp{common}, adem@'as de otros n@'umeros de modelos espec@'{@dotless{i}}ficos. El c@'odigo generado con la opci@'on @option{-mcpu=common} se ejecutar@'a en cualquiera de los procesadores. @cindex Altivec, en PowerPC @cindex @option{-maltivec}, opci@'on que habilita el uso del procesador Altivec en PowerPC @cindex @option{maltivec}, opci@'on que habilita el uso del procesador Altivec en PowerPC La opci@'on @option{-maltivec} habilita el uso del vector Altivec de procesamiento de instrucciones, si el soporte del hardware apropiado est@'a disponible. @cindex multiplicar y a@~nadir instrucci@'on @cindex instrucci@'on fusionada de multiplicaci@'on y suma @cindex instrucci@'on combinada de multiplicaci@'on y suma @cindex @option{-mno-fused-madd}, opci@'on en PowerPC @cindex @option{mno-fused-madd}, opci@'on en PowerPC Los procesadores POWER/PowerPC incluyen una instrucci@'on combinada ``multiplicaci@'on y suma'' @math{a * x + b}, la cual realiza las dos operaciones simult@'aneamente para ganar en velocidad ---esto es referido como una @dfn{fusi@'on} de multiplicaciones y sumas, y es usado por defecto en GCC. Debido a las diferentes formas en que los valores intermedios son redondeados, el resultado de una instrucci@'on fundida puede no tener exactamente igual rendimiento que dos operaciones separadas. En los casos en que es requerida estrictamente la aritm@'etica IEEE, el uso de las instrucciones combinadas puede ser deshabilitado con la opci@'on @option{-mno-fuser-madd}. @cindex error de desbordamiento TOC, en AIX @cindex tabla de contenidos, error de desbordamiento en AIX @cindex error de desbordamiento, para TOC en AIX @cindex AIX, error de desboramiento TOC @cindex @option{-mminimal-toc}, opci@'on en AIX @cindex @option{mminimal-toc}, opci@'on en AIX En sistemas AIX, la opci@'on @option{-mminimal-toc} disminuye el n@'umero de entradas GCC puestas en la @dfn{tabla de contextos} global (TOC) de los ejecutables para anular los errores ``TOC overflow'' en tiempo de enlazado. @cindex @option{-mxl-call}, opci@'on para compatibilidad con compiladores IBM XL en AIX @cindex @option{mxl-call}, opci@'on para compatibilidad con compiladores IBM XL en AIX @cindex compiladores IBM XL, compatibilidad en AIX @cindex compiladores XL, compatibilidad en AIX @cindex AIX, compatibilidad con compiladores IBM XL La opci@'on @option{-mxl-call} realiza el enlazado de archivos objetos de GCC compatible con los compiladores de IBM's XL. @cindex @option{-pthread}, opci@'on en AIX @cindex @option{pthread}, opci@'on en AIX @cindex hilos, en AIX Para aplicaciones que usan hilos POSIX, AIX siempre requiere la opci@'on @option{-pthread} en compilaci@'on, incluso cuando el programa s@'olo se ejecute en modo hilo simple. @node Soporte de m@'ultiples arquitecturas @section Soporte de m@'ultiples arquitecturas @cindex soporte a m@'ultiples arquitecturas, discusi@'on de @cindex MIPS64, soporte a m@'ultiples arquitecturas @cindex Sparc64, soporte a m@'ultiples arquitecturas @cindex PowerPC, soporte a m@'ultiples arquitecturas @cindex ARM, soporte a m@'ultiples arquitecturas @cindex Thumb, formato alternativo de c@'odigo en ARM Un n@'umero de plataformas puede ejecutar c@'odigo para m@'as de una arquitectura. Por ejemplo, plataformas de 64 bits como AMD64, MIPS64, Sparc64 y PowerPC64 soportan la ejecuci@'on de c@'odigo tanto de 32 como de 64 bits. De forma an@'aloga, los procesadores ARM soportan tanto c@'odigo de ARM como un c@'odigo m@'as compacto denominado ``Thumb''. GCC puede ser construido para soportar m@'ultiples arquitecturas en estas plataformas. Por defecto, el compilador generar@'a archivos objetos de 64 bits, pero dando la opci@'on @option{-m32} generar@'a archivos objetos de 32 bits para la correspondiente arquitectura.@footnote{Las opciones @option{-maix64} y @option{-maix32} son empleadas en AIX.} @cindex Itanium, soporte a m@'ultiples plataformas @cindex librer@'{@dotless{i}}as de sistemas, localizaci@'on de Observe que el soporte de m@'ultiples plataformas depende de la disponibilidad de las librer@'{@dotless{i}}as correspondientes. En plataformas de 64 bits que soportan ejecutables tanto de 64 como 32 bits, las librer@'{@dotless{i}}as de 64 bits son a menudo puestas en directorios @file{lib64} en vez de en directorios @file{lib}, p.e. en @file{/usr/lib64} y @file{/lib64}. Las librer@'{@dotless{i}}as de 32 bits se encuentran por defecto en directorios @file{lib} de otras plataformas. Esto permite que las librer@'{@dotless{i}}as tanto de 32 bits como de 64 bits puedan existir con el mismo nombre y en el mismo sistema. Otros sistemas, como el IA64/Itanium, emplea los directorios @file{/usr/lib} y @file{/lib} para las librer@'{@dotless{i}}as de 64 bits. GCC conoce estos caminos y los emplea apropiadamente cuando compila c@'odigo para 64 bits @'o 32 bits. @node Usos de coma flotante @section Usos de coma flotante @cindex coma flotante, problemas de portabilidad @cindex aritm@'etica, coma flotante @cindex diferencias num@'ericas @macro scinum{a,b} @iftex @tex $\a\ \\times 10^{ \b\ }$@comment @end tex @end iftex @ifnottex \a\*10^\b\@comment @end ifnottex @end macro @macro sciexp{a,b} @iftex @tex $\a\^{ \b\ }$@comment @end tex @end iftex @ifnottex \a\^\b\@comment @end ifnottex @end macro @macro scirange{a,b} @iftex @tex $\a\^{\\pm \b\ }$@comment @end tex @end iftex @ifnottex \a\^(+/-\b\)@comment @end ifnottex @end macro @cindex aritm@'etica IEEE El est@'andar IEEE-754 define el comportamiento a nivel de bit de las operaciones aritm@'eticas en coma flotante en todos los procesadores modernos. Esto permite que los programas num@'ericos sean portados entre diferentes plataformas con id@'enticos resultados, en principio. En la pr@'actica, hay a menudo peque@~nas variaciones causadas por las diferencias en el orden de las operaciones (dependiendo de los niveles de compilaci@'on y optimizaci@'on) pero generalemnte son insignificantes. @cindex x86, aritm@'etica en coma flotante @cindex Motorola 680x0, aritm@'etica en coma flotante @cindex procesadores con doble precisi@'on nativa @cindex doble precisi@'on @cindex precisi@'on extendida, procesadores x86 Sin embargo, se pueden apreciar m@'as notables discrepancias cuando se portan programas num@'ericos entre sitemas x86 y otras plataformas, porque la unidad de coma flotante x87 (FPU) en los procesadores x86 procesan los resultados empleando internamente precisi@'on extendida (los valores ser@'an convertidos a doble precisi@'on s@'olo cuando son almacenados en memoria). En contraste, procesadores como SPARC, PA-RISC, Alpha, MIPS y POWER/PowerPC funcionan con valores en doble precisi@'on nativos.@footnote{Los procesadores Motorola 68k tambi@'en usan registros de precisi@'on extendida, como el x86.} Las diferencias entre estas implementaciones provocan cambiar el comportamiento en el redondeo y en undeflow/overflow, porque los valores intermedios tienen mayor precisi@'on relativa y rango de exponentes cuando son procesados en precisi@'on extendida.@footnote{Para tener cantidades en registros de precisi@'on extendida x87 la precisi@'on relativa es @scinum{5.42,-20} y el rango del exponente es @scirange{10,4932}. Los valores est@'andar de doble precisi@'on tienen una precisi@'on relativa de @scinum{2.22,-16} y un rango del exponente de @scirange{10,308}.} En particular, las comparaciones que afectan a valores en precisi@'on extendida pueden fallar donde los valores en doble precisi@'on equivalente deber@'{@dotless{i}}a comparar igual. @cindex redondeo, aritm@'etica de coma flotante @cindex desbordamiento, aritm@'etica de coma flotante @cindex desbordamiento inferior, aritm@'etica de coma flotante Para evitar esta incompatibilidad, la unidad de coma flotante (FPU) ofrece a menudo un modo del hardware redondeando la doble precisi@'on. En este modo el resultado de cada operaci@'on en coma flotante con precisi@'on extendida es redondeada a doble precisi@'on en registros en coma flotante por la FPU. Es importante observar que el redondeo s@'olo afecta a la precisi@'on, y no al rango del exponente, as@'{@dotless{i}} el resultado es un formato h@'{@dotless{i}}brido de doble precisi@'on con un rango extendido de exponentes. @cindex FreeBSD, aritm@'etica de coma flotante @cindex NetBSD, aritm@'etica de coma flotante @cindex OpenBSD; aritm@'etica de coma flotante @cindex GNU/Linux, aritm@'etica de coma flotante @cindex kernel Linux, coma flotante @cindex @code{fldcw} activar modo de coma flotante @cindex @code{asm}, palabra reservada de extensi@'on @cindex instrucci@'on m@'aquina, palabra reservada @code{asm} En sistemas BSD tales como FreeBSD, NetBSD y OpenBSD, el modo hardware de redondeo de doble precisi@'on est@'a por defecto. Alcanzado la mayor compatibilidad con plataformas con doble precisi@'on nativa. En sistemas x86 GNU/Linux el modo por defecto es precisi@'on extendida (con la aspiraci@'on de suministrar un incremento en la precisi@'on). Para habilitar el modo de redondeo de doble precisi@'on es necesario anular la configuraci@'on por defecto en la base por procesos usando la instrucci@'on de m@'aquina @sc{fldcw} ``floating-point load control-word''.@footnote{El sistema operativo guarda y recupera la palabra de control cuando alterna entre procesos, as@'{@dotless{i}} que cada proceso mantiene su propia configuraci@'on.} Una simple funci@'on puede ser invocada para ejecutar estas instrucciones que se muestran a continuaci@'on. Se usa la palabra reservada de la extensi@'on de GCC @code{asm} para insertar la instrucci@'on espec@'{@dotless{i}}fica en la salida del lenguaje ensamblador: @example @verbatiminclude setfpu.es.c @end example @noindent La apropiada configuraci@'on de @code{mode} para el redondeo en doble precisi@'on es @code{0x27F}. El valor del modo tambi@'en controla el comportamiento del manejo de la excepci@'on de coma flotante y la direcci@'on de redondeo (para m@'as detalles vea el manual de referencia de los procesadores Intel y AMD). @cindex manejando de excepci@'on de coma flotante @cindex manejando excepci@'on, coma flotante En sistemas x86 GNU/Linux, la funci@'on anterior puede ser llamada al inicio de cualquier programa para deshabilitar precisi@'on excesiva. Esto reproducir@'a el resultado de los procesadores de doble precisi@'on nativa, en ausencia de desbordamientos por exceso y por defecto. El siguiente programa demuestra los diferentes modos de redondeo: @example @verbatiminclude fptest2.es.c @end example @noindent En sistemas x86 GNU/Linux la comparaci@'on @code{c == a / b} puede producir un resultado inesperado si @code{c} es tomado desde memoria (doble precisi@'on) mientras que @code{a / b} es procesado en precisi@'on extendida, porque la fracci@'on 3/7 tiene diferentes representaciones en precisi@'on doble y extendida. @example $ gcc -Wall fptest2.c $ ./a.out unexpecedt result @end example @noindent Configurando el modo de redondeo hardware a doble precisi@'on previene que lo anterior suceda: @example $ gcc -Wall -DDOUBLE fptest2.c $ ./a.out comparison succeeds @end example @noindent Observe que la palabra de control de la coma flotante afecta al entorno completo del proceso, incluyendo las funciones de librer@'{@dotless{i}}as C que sean invocadas. Una consecuencia de esto es que la aritm@'etica en coma flotante es reducida eficientemente a doble precisi@'on, desde que se conf@'{@dotless{i}}a en operaciones de precisi@'on extendida. @cindex aritm@'etica en coma flotante @c @cindex @option{-ffloat-store} @c The option @option{-ffloat-store} is sometimes suggested as a way to @c avoid problems with excess precision---it forces floating-point values @c to be stored in memory when they are assigned to a variable. However, @c it does not affect intermediate expressions or conditionals, and can @c slow down programs significantly. If necessary, it is possible to force @c a single variable to remain in memory is by declaring it @c @code{volatile}. @c @example @c @verbatiminclude coerce.h @c @end example @c @noindent @c @example @c @c @verbatiminclude fp.c @c @end example @c @noindent @cindex precisi@'on SSE/SSE2 La palabra de control de la coma flotante s@'olo afecta al comportamiento de FPU x87. Las operaciones en coma flotante procesadas con instrucciones de SSE y SSE2 son siempre llevadas a cabo en doble precisi@'on nativa. As@'{@dotless{i}}, las opciones combinadas @example $ gcc -Wall -msse2 -mfpmath=sse ...@end example @noindent son a menudo suficientes para eliminar los efectos de la precisi@'on extendida. Sin embargo, algunas operaciones (tales como funciones transcendentales) no est@'an disponibles en las extensiones SSE/SSE2 y ser@'an procesadas por el FPU x87. @node Portabilidad de los tipos con signo y sin signo @section Portabilidad de los tipos con signo y sin signo @cindex opci@'on @code{char} con signo @cindex opci@'on @code{char} sin signo @cindex @code{char}, portabilidad con signo versus sin signo Los est@'andares C y C++ permiten que el tipo car@'acter @code{char} sea con signo o sin signo, dependiendo de la plataforma y el compilador. La mayor@'{@dotless{i}}a de los sistemas, incluidos x86 GNU/Linux y Microsoft Windows, usan @code{char} con signo, pero aquellos basados en PowerPC y procesadores @sc{arm} usan habitualmente @code{char} sin signo.@footnote{MacOS X (Drawin) en PowerPC usa @code{char} con signo, por consistencia con otras arquitecturas Darwin.} Esto puede causar resultados inexperados cuando se portan programas entre plataformas que tienen diferentes tipos @code{char} por defecto. El siguiente c@'odigo demuestra la diferencia entre plataformas con tipos @code{char} con signo y sin signo: @example @verbatiminclude signed.es.c @end example @noindent Con un @code{char} sin signo, la variable @code{c} toma el valor 255, pero con un @code{char} con signo viene a ser @math{-1}. La forma correcta de manipular variables @code{char} en C es a trav@'es de las funciones portables declaradas en @file{ctype.h}, tales como @code{isalpha}, @code{isdigit} y @code{isblank}, en vez de sus valores num@'ericos. El comportamiento de las expresiones condicionales no portables tales como @code{c > 'a'} depende del signado del tipo @code{char}. Si se requiere expl@'{@dotless{i}}citamente una versi@'on con signo o sin signo en cierto punto de un programa, se puede especificar usando @code{signed char} o @code{unsigned char}. For existing programs which assume that @code{char} is signed or unsigned, GCC provides the options @option{-fsigned-char} and @option{-funsigned-char} to set the default type of @code{char}. Using these options, the example code above compiles cleanly with @option{-Wall -W} when @code{char} is unsigned: @cindex @option{-funsigned-char}, opci@'on @cindex @option{-fsigned-char}, opci@'on @example $ gcc -Wall -W -funsigned-char signed.c $ ./a.out char is unsigned (c = 255) @end example @noindent However, when @code{char} is signed the value 255 wraps around to @math{-1}, giving a warning when compiled with @option{-Wall -W}: @example $ gcc -Wall -W -fsigned-char signed.c signed.c: In function `main': signed.c:7: warning: comparison is always false due to limited range of data type $ ./a.out char is signed (c = -1) @end example @noindent El mensaje de aviso @cite{``comparison es always true/false due to limited range of data type''} es un s@'{@dotless{i}}ntoma de que el c@'odigo asume una definici@'on de @code{char} que difiere del tipo actual. El problema m@'as com@'un en la escritura de c@'odigo asumiendo el tipo @code{char} con signo ocurre con las funciones @code{getc}, @code{fgetc} y @code{getchar} (las cuales leen caract@'eres de un archivo). Tienen un tipo de retorno de @code{int}, no @code{char}, y esto permite el uso de un valor especial @math{-1} (definido como @code{EOF}) para indicar un error de final de archivo. Desafortunadamente, muchos programas han sido escritos guardando incorrectamente este valor de retorno directamente en una variable @code{char}. Aqu@'{@dotless{i}} est@'a el t@'{@dotless{i}}pico ejemplo: @example @verbatiminclude testgetc.es.c @end example @noindent Esto s@'olo funciona en plataformas que por defecto tienen el tipo @code{char} con signo.@footnote{Esto es adem@'as un sutil error en plataformas con @code{char} con signo ---el car@'acter @sc{ascii} 255 es falsamente interpretado como una condici@'on de final de archivo.} En plataformas que usan @code{char} sin signo el mismo c@'odigo puede fallar, porque el valor @math{-1} se convierte en un 255 cuando se almacena en un @code{unsigned char}. Esto es normalmente causa de bucles infinitos porque el final del archivo no puede ser reconocido.@footnote{Si se mostrase, el car@'acter con c@'odigo 255 a menudo aparece como @code{@'"y}.} Para ser portable, el programa debe comprobar el valor de retorno como un entero antes de forzarlo a @code{char}, como a continuaci@'on: @example @verbatiminclude testgetc2.es.c @end example @noindent @cindex opci@'on para campos orientados a bit con signo @cindex opci@'on para campos orientados a bit sin signo @cindex campos orientados a bit, portabilidad con signo versus sin signo @cindex @option{-funsigned-bitfields}, opci@'on @cindex @option{-fsigned-bitfields}, opci@'on Las mismas consideraciones de esta secci@'on se aplican a las definiciones de campos orientados a bit en estructuras, las cuales pueden ser por defecto con signo o sin signo. En GCC, el tipo por defecto para los campos orientados a bit puede ser controlado usando las opciones @option{-fsigned-bitfields} y @option{-funsigned-bitfields}. @node Resoluci@'on de problemas @chapter Resoluci@'on de problemas @cindex opciones de resoluci@'on de problemas @cindex opciones de ayuda @cindex opci@'on de ayuda en l@'{@dotless{i}}nea de comandos GCC proporciona varias opciones de ayuda para ayudar en la resoluci@'on de problemas con el proceso de compilaci@'on. Todas las opciones descritas en este cap@'{@dotless{i}}tulo funciona tanto con @code{gcc} como con @code{g++}. @menu * Opciones de ayuda en l@'{@dotless{i}}nea de comandos:: * N@'umeros de versi@'on:: * Compilaci@'on verbosa:: * Parando un programa en un bucle infinito:: * Previniendo un uso excesivo de memoria:: @end menu @node Opciones de ayuda en l@'{@dotless{i}}nea de comandos @section Opciones de ayuda en l@'{@dotless{i}}nea de comandos @cindex @option{--help}, opci@'on para mostrar las opciones de l@'{@dotless{i}}nea de comandos Para tener un breve recordatorio de varias opciones del comando, GCC tiene una opci@'on de ayuda que muestra un resumen de alto nivel de las opciones del comando GCC: @example $ gcc --help @end example @noindent @cindex opci@'on de ayuda verbosa @cindex @option{-v}, opci@'on para compilaci@'on verbosa @cindex @option{v}, opci@'on para compilaci@'on verbosa Para mostrar una lista completa de opciones para @code{gcc} y sus programas asociados, tales como el Enlazador de GNU y el Ensamblador de GNU, usa la opci@'on de arriba con la opci@'on verbosa (@option{-v}: @example $ gcc -v --help @end example @noindent La lista completa de opciones producidas por este comando es extremadamente larga ---se puede desear paginar a trav@'es de @'esta usando el comando @code{more}, o redirigir la salida a un fichero por referencia: @example $ gcc -v --help 2>&1 | more @end example @node N@'umeros de versi@'on @section N@'umeros de versi@'on Se puede encontrar el n@'umero de versi@'on de @code{gcc} usando la opci@'on de versi@'on @cindex n@'umero de versi@'on de GCC, mostrando @cindex @code{--version}, opci@'on para mostrar el n@'umero de versi@'on @example $ gcc --version gcc (Debian 4.6.1-4) 4.6.1 @end example @noindent El n@'umero de versi@'on es importante cuando se investigan los problemas de compilaci@'on debido a que las versiones antiguas de GCC pueden no tener algunas funcionalidades que un programa usa. El n@'umero de versi@'on tiene las forma @var{major-version.minor-version} @'o @var{major-version.minor-version.micro-version}, d@'onde el tercer n@'umero de versi@'on ``micro'' (como se muestra arriba) es usado para la subsiguiente entrega de correcci@'on de errores en una serie de entregas. @cindex n@'umero de versi@'on mayor, de GCC @cindex n@'umero de versi@'on menor, de GCC @cindex nivel de parche, de GCC Pueden encontrarse m@'as detalles acerca de la versi@'on usando @option{-v}: @example $ gcc -v Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/i386-linux-gnu/gcc/ /i486-linux-gnu/4.6.1/lto-wrapper Target: i486-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.1-4' --with-bugurl=file:///usr/share/doc/gcc-4.6/ /README.Bugs --enable-languages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-multiarch --with-multiarch-defaults=i386-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/i386-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib/i386-linux-gnu --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.6.1 (Debian 4.6.1-4) @end example @noindent @cindex archivos de configuraci@'on de GCC @cindex @code{specs}, directorio de archivos de configuraci@'on del compilador Incluye informaci@'on en los flags de construcci@'on al mismo compilador y al archivo de configuraci@'on instalado, @file{specs}. @node Compilaci@'on verbosa @section Compilaci@'on verbosa @cindex compilaci@'on verbosa, opci@'on @option{-v} La opci@'on @option{-v} tambi@'en puede ser usada para mostrar informaci@'on detallada acerca de la secuencia exacta de comandos usados para compilar y enlazar un programa. Aqu@'{@dotless{i}} hay un ejemplo que muestra la compilaci@'on verbosa del programa @cite{Hola Mundo}: @example $ gcc -v -Wall hola.es.c Using built-in specs. COLLECT_GCC=gcc COLLECT_LTO_WRAPPER=/usr/lib/i386-linux-gnu/gcc/ /i486-linux-gnu/4.6.1/lto-wrapper Target: i486-linux-gnu Configured with: ../src/configure -v --with-pkgversion='Debian 4.6.1-4' --with-bugurl=file:///usr/share/doc/gcc-4.6/ /README.Bugs --enable-la nguages=c,c++,fortran,objc,obj-c++,go --prefix=/usr --program-suffix=-4.6 --enable-shared --enable-multiarch --with-multiarch-defaults=i386-linux-gnu --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib/i386-linux-gnu --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.6 --libdir=/usr/lib/i386-linux-gnu --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-plugin --enable-objc-gc --enable-targets=all --with-arch-32=i586 --with-tune=generic --enable-checking =release --build=i486-linux-gnu --host=i486-linux-gnu --target=i486-linux-gnu Thread model: posix gcc version 4.6.1 (Debian 4.6.1-4) COLLECT_GCC_OPTIONS='-v' '-Wall' '-mtune=generic' '-march=i586' /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/cc1 -quiet -v hola.es.c -quiet -dumpbase hola.es.c -mtune=generic -march=i586 -auxbase hola.es -Wall -version -o /tmp/cchpM0t3.s GNU C (Debian 4.6.1-4) version 4.6.1 (i486-linux-gnu) compiled by GNU C version 4.6.1, GMP version 5.0.1, MPFR version 3.0.1-p3, MPC version 0.9 warning: GMP header version 5.0.1 differs from library version 5.0.2. GGC heuristics: --param ggc-min-expand=46 --param ggc-min-heapsize=31802 ignoring nonexistent directory "/usr/local/include/i386-linux-gnu" ignoring nonexistent directory "/usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/../ /../../../../i486-linux-gnu/include" #include "..." search starts here: #include <...> search starts here: /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/include /usr/local/include /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/ /include-fixed /usr/include/i386-linux-gnu /usr/include End of searchlist. GNU C (Debian 4.6.1-4) version 4.6.1 (i486-linux-gnu) compiled by GNU C version 4.6.1, GMP version 5.0.1, MPFR version 3.0.1-p3, MPC version 0.9 warning: GMP header version 5.0.1 differs from library version 5.0.2. GGC heuristics: --param ggc-min-expand=46 --param ggc-min-heapsize=31802 Compiler executable checksum: 2cfae8623c84fd817bfff483158c4341 COLLECT_GCC_OPTIONS='-v' '-Wall' '-mtune=generic' '-march=i586' as --32 -o /tmp/ccQxW8a5.o /tmp/cchpM0t3.s COMPILER_PATH=/usr/lib/i386-linux-gnu/gcc/ /i486-linux-gnu/4.6.1/: /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/: /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/: /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/: /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/ LIBRARY_PATH=/usr/lib/i386-linux-gnu/gcc/ /i486-linux-gnu/4.6.1/: /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/ /../../../: /lib/:/usr/lib/:/usr/lib/i386-linux-gnu/ COLLECT_GCC_OPTIONS='-v' '-Wall' '-mtune=generic' '-march=i586' /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/ /collect2 --build-id --no-add-needed --eh-frame-hdr -m elf_i386 --hash-style=both -dynamic -linker /lib/ld-linux.so.2 /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/ /../../../crt1.o /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/ /../../../crti.o /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/ /crtbegin.o -L/usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1 -L/usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/ /../../.. -L/usr/lib/i386-linux-gnu/tmp/ccQxW8a5.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -l gcc --as-needed -lgcc_s --no-as-needed /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/ /crtend.o /usr/lib/i386-linux-gnu/gcc/i486-linux-gnu/4.6.1/ /../../../crtn.o @end example @noindent La salida producida por @option{-v} puede ser @'util siempre y cuando haya un problema con el proceso de compilaci@'on en s@'{@dotless{i}}. Esto muestra las rutas completas usadas para buscar los ficheros de cabecera y librer@'{@dotless{i}}as, los s@'{@dotless{i}}mbolos de preprocesador predefinidos, y los ficheros objeto y librer@'{@dotless{i}}as usadas para enlazar. @node Parando un programa en un bucle infinito @section Parando un programa en un bucle infinito @cindex bucle infinito, parando @cindex control-C, interrumpir @cindex se@~nal SIGINT @cindex @code{attach}, depuraci@'on de un programa en ejecuci@'on Un programa que se mete en un bucle infinito o se ``cuelga'' puede ser dif@'{@dotless{i}}cil de depurar. En la mayor@'{@dotless{i}}a de los sistemas un proceso en primer plano puede ser detenido pulsando @kbd{Control-C}, que env@'{@dotless{i}}a una se@~nal de interrupci@'on (@sc{sigint}). Sin embargo, esto no ayuda en la depuraci@'on del problema ---la se@~nal @sc{sigint} termina el proceso sin producir un core dump. Un enfoque m@'as sofisticado es @dfn{adjuntar} el proceso en ejecuci@'on a un depurador e inspeccionarlo de manera interactiva. Por ejemplo, aqu@'{@dotless{i}} hay un programa simple con un bucle infinito: @example @verbatiminclude bucle.es.c @end example @noindent Para adjuntar el programa y depurarlo, el c@'odigo deber@'{@dotless{i}}a ser compilado con la opci@'on de depuraci@'on @option{-g}: @example $ gcc -Wall -g loop.es.c $ ./a.out @r{(program hangs)} @end example @noindent @cindex identificador de proceso, encontrando Una vez el ejecutable est@'a ejecut@'andose, se necesitar@'a encontrar su identificador de proceso (@sc{pid}). Esto se puede hacer desde otra sesi@'on con el comando @code{ps x}: @example $ ps x PID TTY STAT TIME COMMAND ... ..... .. .... 2333 pts/0 R+ 0:16 ./a.out @end example @noindent En este caso el identificador de proceso es 2333, y ahora se puede adjuntar con @code{gdb}. El depurador deber@'{@dotless{i}}a ser iniciado en el directorio que contiene el ejecutable y su c@'odigo fuente:@footnote{De manera alternativa, las rutas apropiadas pueden ser configuradas en @code{gdb} usando los comandos @code{file} y @code{directory}.} @example $ gdb a.out GNU gdb (GDB) 7.3-debian ... (gdb) attach 2333 Attaching to program: a.out, process 2333 Reading symbols from /lib/i386-linux-gnu/i686/cmov/libc.so.6...(no debugging symbols found)...done. Loaded symbols for /lib/i386-linux-gnu/i686/cmov/libc.so.6 Reading symbols from /lib/ld-linux.so.2...(no debugging symbols found)...done. Loaded symbols for /lib/ld-linux.so.2 0x080483c5 in main () at loop.c:5 5 while (1) @{ i++; @}; (gdb) @end example @noindent La salida muestra la l@'{@dotless{i}}nea que se ejecut@'o en el punto en el que el depurador se adjunt@'o al proceso. El programa adjunto se pausa pero todav@'{@dotless{i}}a `vive' ---este puede examinado interactivamente y contin@'ua o termina (con el comando @code{kill}) si es necesario: @example (gdb) print i $1 = 1960534048 (gdb) kill Kill the program being debugged? (y or n) y (gdb) @end example @noindent @cindex se@'nal SIGQUIT Si se quiere parar un proceso inmediatamente y crear un core dump, el comando de shell @code{kill -3 @var{pid}} (d@'onde @var{pid} es el identificador de proceso) enviar@'a una se@~nal @sc{sigquit}. La se@~nal @sc{sigquit} dispara un core dump, no como @sc{sigint}. N@'otese que si los core dump fueran deshabilitados cuando el proceso fu@'e iniciado, ning@'un fichero core se producir@'a (@pxref{Examinando archivos core}). @node Previniendo un uso excesivo de memoria @section Previniendo un uso excesivo de memoria @cindex uso de memoria, limitando @cindex uso de memoria virtual, limitando @cindex comando @command{ulimit} Algunas veces un error de programaci@'on har@'a que un proceso gestione grandes cantidades de memoria, consumiendo toda la @sc{ram} en un sistema. Para prevenir esto, el comando GNU Bash @command{ulimit -v @var{limit}} se puede usar para restringir la cantidad de memoria virtual disponible en cada proceso. El l@'{@dotless{i}}mite es medido en kilobytes y se aplica a nuevos procesos iniciados en la shell actual. Por ejemplo, @example $ ulimit -v 4096 @end example @noindent limitar@'a los siguientes procesos a 4 megabytes de memoria virtual (4096k). Por defecto el l@'{@dotless{i}}mite no puede incrementarse en la misma sesi@'on una vez ha sido establecido, as@'{@dotless{i}} es mejor comenzar una shell distinta para operaciones @code{ulimit} reducidas. De manera alternativa, se puede establecer un @dfn{l@'{@dotless{i}}mite blando} (que puede ser deshecho) con las opciones @option{-S -v}. Adicionalmente para prevenir derroche de procesos, limitando la cantidad de memoria que un programa puede reservar permite una forma de comprobar la robusted del manejo de condiciones @dfn{out of memory}. Un artificial l@'{@dotless{i}}mite bajo se puede usar para simular ejecuciones fuera de memoria ---un programa bien escrito no debe fallar en estos casos. @c The following program tries to allocate 32 megabytes of memory using @c @code{malloc}: @c @example @c @verbatiminclude outofmem.c @c @end example @c @noindent @c Under normal circumstances, the program executes without problems: @c @example @c $ gcc -Wall outofmem.c @c $ ./a.out @c Allocating 32 megabytes... success @c @end example @c If we restrict the available virtual memory to 4 megabytes, the call to @c @code{malloc} will fail: @c @example @c $ ulimit -v 4096 @c $ ./a.out @c Allocating 32 megabytes... FAILED @c @end example El comando @command{ulimit} soporta otras opciones incluyendo @option{-p}, que restringe el n@'umero de procesos hijos que pueden ser creados, y @option{-t}, que establece un l@'{@dotless{i}}mite en el n@'umero de segundos de @sc{cpu} en el que un proceso puede ejecutarse. La lista completa de configuraciones puede mostrarse con el comando @code{ulimit -a}. Para mostrar m@'as informaci@'on acerca del comando @code{ulimit}, escribe @code{help ulimit} en una Shell de Bash. @node Utilidades relativas al compilador @chapter Utilidades relativas al compilador @cindex utilidades relativas al compilador @cindex utilidades, relativas al compilador Este cap@'{@dotless{i}}tulo describe un conjunto de herramientas que son muy utilizadas junto a GCC. Estas incluyen el archivador GNU @code{ar}, para crear librer@'{@dotless{i}}as, y los programas de comprobaci@'on de perfil y cobertura, @code{gprof} y @code{gcov}. @menu * Creando una librer@'{@dotless{i}}a con el archivador de GNU:: * Usando el profiler gprof:: * Coverage testing with gcov:: @end menu @node Creando una librer@'{@dotless{i}}a con el archivador de GNU @section Creando una librer@'{@dotless{i}}a con el archivador de GNU @cindex @code{ar}, GNU archiver @cindex librer@'{@dotless{i}}as, creando con @code{ar} El archivador GNU @code{ar} combina una colecci@'on de archivos objeto en un simple fichero de archivo, conocido tambi@'en como una @dfn{librer@'{@dotless{i}}a}. Un fichero de archivo es simplemente una forma conveniente de distribuir un gr@'an n@'umero de archivos objeto juntos (como se describi@'o anteriormente en @ref{Enlazando con librer@'{@dotless{i}}as externas}). Para demostrar el uso del archivador GNU se crear@'a una peque@~na librer@'{@dotless{i}}a @file{libhola.a} conteniendo dos funciones @code{hola} y @code{adios}. El primer archivo objeto ser@'a generado desde el c@'odigo fuente de la funci@'on @code{hola}, en el archivo @file{hola_fn.es.c}: @example @verbatiminclude hola_fn.es.c @end example @noindent El segundo archivo objeto ser@'a generado con el archivo fuente @file{adios_fn.es.c}, que contiene la funci@'on @code{adios}: @example @verbatiminclude adios_fn.es.c @end example @noindent Ambas funciones usan el archivo de cabecera @file{hola.es.h}, ahora con un prototipo para la funci@'on @code{adios()}: @example @verbatiminclude hola.es.h @end example @noindent El c@'odigo fuente puede ser compilado a los archivos objeto @file{hola_fn.o} y @file{adios_fn.o} usando el comando: @example $ gcc -Wall -c hola_fn.es.c $ gcc -Wall -c adios_fn.es.c@end example @noindent @cindex @option{cr}, opci@'on para crear/reemplazar archivos de librer@'{@dotless{i}}as Estos archivos objeto pueden ser combinados en una librer@'{@dotless{i}}a usando la siguiente l@'{@dotless{i}}nea de comando: @example $ ar cr libhola.a hola_fn.o adios_fn.o@end example @noindent La opci@'on @option{cr} significa ``crear y reemplazar''.@footnote{Observe que @code{ar} no requiere el prefijo @samp{-} para estas opciones.} Si la librer@'{@dotless{i}}a no existe, primero ser@'a creada. Si la librear@'{@dotless{i}}a ya existe, el archivo original con el mismo nombre ser@'a reemplazado por el nuevo archivo especificado en la l@'{@dotless{i}}nea de comando. El primer argumento @file{libhola.a} es el nombre de la librer@'{@dotless{i}}a. El resto de argumentos son los nombres de los archivos objeto que ser@'an copiados a la librer@'{@dotless{i}}a. @cindex @option{t}, opci@'on para ver la tabla de contenidos de una librer@'{@dotless{i}}a @cindex tabla de contenidos, en librer@'{@dotless{i}}as @code{ar} El archivador @code{ar} adem@'as suministra una opci@'on de ``tabla de contenidos'' @option{t} para listar los archivos objeto de una librar@'{@dotless{i}}a existente: @example $ at t libhola.a hola_fn.o adios_fn.o@end example @noindent Observe que cuando la librer@'{@dotless{i}}a sea distribuida, los archivos cabecera de las funciones y variables p@'ublicas ser@'a suministrado para que tambi@'en est@'e disponible, as@'{@dotless{i}} el usuario final puede incluirlos y obtener los prototipos correctos. Se puede escribir ahora un programa usando las funciones de la recien creada librer@'{@dotless{i}}a: @example @verbatiminclude main3.es.c @end example @noindent Este archivo puede ser compilado con la siguiente l@'{@dotless{i}}nea de comando, como est@'a descrito en @ref{Enlazando con librer@'{@dotless{i}}as externas}, asumiendo que la librer@'{@dotless{i}}a @file{libhola.a} est@'a almacenada en el directorio actual: @example $ gcc -Wall main3.c libhello.a -o hello @end example @noindent El programa principal es enlazado junto a los archivos objeto encontrados en el archivo de librer@'{@dotless{i}}a @file{libhola.a} para producir el ejecutable final. La opci@'on de atajo de enlazado de la librer@'{@dotless{i}}a se puede usar para enlazar el programa, sin necesidad de especificar expl@'{@dotless{i}}citamente un camino completo a la librer@'{@dotless{i}}a: @example $ gcc -Wall -L. main3.c -lhello -o hello @end example @noindent La opci@'on @option{-L.} es necesaria para a@~nadir el directorio actual al camino de b@'usqueda de librer@'{@dotless{i}}as. El ejecutable resultante se puede ejecutar como habitualmente: @example $ ./hola @exclamdown{}Hola, cualquiera! @exclamdown{}Adios!@end example @noindent Se muestra la salida de ambas funciones @code{hola} y @code{adios} definidas en la librer@'{@dotless{i}}a. @node Usando el profiler gprof @section Usando el profiler @code{gprof} @cindex profiling, con @code{gprof} @cindex @code{gprof}, GNU Profiler El GNU profiler @code{gprof} es una muy usada herramienta para medir el rendimiento de un programa ---graba el n@'umero de llamadas de cada funci@'on y contabiliza el tiempo que emplea en ello, en una base por funci@'on. Las funciones que consumen largas fracciones del tiempo de ejecuci@'on pueden ser identificas f@'acilmente a partir de la salida de @code{gprof}. Mejorar la velocidad de un programa requiere primero concentraci@'on sobre aquellas funciones que dominan el tiempo de ejecuci@'on completamente. @cindex secuencia de Collatz Se usar@'a @code{gprof} para examinar el rendimiento de un peque@~no programa num@'erico que procesar@'a una larga secuencia irresuelta @cite{Collatz conjeture} en matem@'aticas.@footnote{American Mathematical Monthly, Volume 92 (1985), 3--23} La conjetura de Gollatz afecta a secuencias definidas por la regla: @tex $$ x_{n+1} \leftarrow \cases{ x_n / 2 & si $x_n$ es par\cr 3 x_n + 1 & si $x_n$ es impar\cr} $$ @end tex @ifinfo @example x_@{n+1@} <= x_@{n@} / 2 si x_@{n@} es par 3 x_@{n@} + 1 si x_@{n@} es impar@end example @end ifinfo @noindent La secuencia es iterada desde el valor inicial @math{x_0} hasta que termina con el valor 1. De acuerdo con la conjetura, todas las secuencias terminar@'an eventualmente ---el programa mostrar@'a las largas secuencias como incrementos de @math{x_0}. El archivo fuente @file{collatz.es.c} contiene tres funciones: @code{main}, @code{nseq} y @code{step}: @smallexample @verbatiminclude collatz.es.c @end smallexample @noindent @cindex @option{-pg}, opci@'on para habilitar profiling @cindex @option{pg}, opci@'on para habilitar profiling @cindex habilitar profiling, opci@'on @option{-pg} Para usar profiling, el programa debe ser compilado y enlazado con la opci@'on de profiling @option{-pg}: @example $ gcc -Wall -c -pg collatz.es.c $ gcc -Wall -pg collatz.o@end example @noindent @cindex ejecutable instrumentado, para an@'alisis Esto crear@'a un ejecutable @dfn{instrumented} que contiene instrucciones adicionales para registrar el tiempo consumido en cada funci@'on. Si el programa consiste en m@'as de un archivo fuente la opci@'on @option{-pg} se debe usar cuando se compila cada archivo fuente, y ser@'a usado en el enlazado de los archivos objetos para crear el ejecutable final (como se muestra anteriormente). Es un error com@'un olvidar la opci@'on @option{-pg} en el enlazado, lo cual evita que el profiling registre mucha informaci@'on @'util. El ejecutable se debe ejecutar para obtener los datos del profiling: @example $ ./a.out @r{(la salida normal del programa es mostrada)}@end example @noindent @cindex @code{gmon.out}, archivo de datos para @code{gprof} Mientras est@'a corriendo el ejecutable instrumentado, datos de profiling son silenciosamente escritos en el archivo @file{gmon.out} en el directorio actual. Puede se analizado con @code{gprof} dando el nombre del ejecutable como argumento: @example $ gprof a.out Flat profile: Each sample counts as 0.01 seconds. % cumul. self self total time seconds seconds calls us/call us/call name 68.59 2.14 2.14 62135400 0.03 0.03 step 31.09 3.11 0.97 499999 1.94 6.22 nseq 0.32 3.12 0.01 main @end example @noindent La primera columna de los datos muestra que el programa emplea la mayor@'{@dotless{i}}a de su tiempo (casi del 70%) en la funci@'on @code{step}, y el 30% en @code{nseq}. Consecuentes esfuerzos para decrementar el tiempo de ejecuci@'on debe concentrarse en esta forma. En comparaci@'on, el tiempo empleado en la funci@'on @code{main} es completamente imperceptible (menos del 1%). Las otras columnas de la salida suministran informaci@'on del n@'umero total de llamadas que son hechas a las funciones, y el tiempo gastado en cada funci@'on. Informaci@'on adicional del tiempo de ejecuci@'on se muestra con @code{gprof} pero aqu@'{@dotless{i}} no se muestra. Un completo detalle se puede encontrar en el manual ``@cite{GNU gprof ---El GNU Profiler}'', de Jay Fenlason y Richard Stallman. @node Coverage testing with gcov @section Test de cobertura con @code{gcov} @cindex test de cobertura, con @code{gcov} @cindex @code{gcov}, GNU coverage testing tool La herramienta de test de cobertura GNU @code{gcov} analiza el n@'umero de veces que cada l@'{@dotless{i}}nea del programa es ejecutada. Esto permite encontrar @'areas del c@'odigo que no son usadas, o que no se ejecutan en los tests. Cuando se combinan la informaci@'on de perfilaci@'on con la informaci@'on de cobertura se logra aumentar la velocidad de un programa concentr@'andose en l@'{@dotless{i}}neas espec@'{@dotless{i}}ficas del c@'odigo fuente. Se usar@'a el ejemplo siguiente para demostrar @code{gcov}. Este programa recorre los n@'umeros del 1 al 9 y comprueba su divisibilidad con el operador m@'odulo (@code{%}). @example @verbatiminclude cov.es.c @end example @noindent Para habilitar los test de cobertura el programa debe ser compilado con las siguientes opciones: @example $ gcc -Wall -fprofile-arcs -ftest-coverage cov.es.c@end example @noindent @cindex @option{-fprofile-arcs}, opci@'on para instrucciones de bifurcaci@'on @cindex @option{fprofile-arcs}, opci@'on para instrucciones de salto @cindex @option{-ftest-coverage}, opci@'on para registro de cobertura @cindex @option{ftest-coverage}, opci@'on para registro de cobertura @cindex ejecutable instrumentado, para test de cobertura @cindex saltos, instrumentando para test de cobertura Esto crear@'a un ejecutable instrumentado que contiene instrucciones adicionales que registran el n@'umero de veces que cada l@'{@dotless{i}}nea del programa es ejecutada. La opci@'on @option{-ftest-coverage} a@~nade instrucciones para contabilizar el n@'umero de veces que las l@'{@dotless{i}}neas individuales son ejecutadas, mientras que @option{-fprofile-arcs} incorpora instrucciones de c@'odigo por cada bifurcaci@'on del programa. Las instrucciones de bifurcaci@'on registran la frecuencia de los diferentes caminos que toman las instrucciones @samp{if} y otras condicionales. El ejecutable debe ser ejecutado para crear los datos de cobertura: @example $ ./a.out 3 es divisible por 3 6 es divisible por 3 9 es divisible por 3@end example @noindent Los datos de la ejecuci@'on son escritos en varios archivos con extensiones @file{.bb}, @file{.bbg} y @file{.da} respectivamente en el directorio actual. Estos datos pueden ser analizados usando el comando @code{gcov} y el nombre del archivo fuente: @example $ gcov cov.es.c 88.89% of 9 source lines executed in file cov.es.c Creating cov.es.c.gcov @end example @noindent El comando @code{gcov} produce una anotaci@'on de la versi@'on del archivo fuente original, con la extensi@'on @file{.gcov}, conteniendo los contadores de los n@'umeros de veces que cada l@'{@dotless{i}}nea fu@'e ejecutada: @example @verbatiminclude cov_c_gcov @end example @noindent Los contadores de l@'{@dotless{i}}neas pueden verse en la primera columna. Las l@'{@dotless{i}}neas que no son ejecutadas est@'an marcadas con almohadillas @samp{######}. El comando @samp{grep '######' *.gcov} se puede usar para encontrar las partes que no est@'an siendo usadas. @node Como funciona el compilador @chapter Como funciona el compilador @cindex compilaci@'on, etapas internas de @cindex etapas de compilaci'on, usadas internamente @cindex compilador, como funciona internamente @cindex ensamblador, @code{as} @cindex preprocesador, @code{cpp} @cindex enlazador, @code{ld} @cindex archivador, @code{ar} Este cap@'{@dotless{i}}tulo describe en detalle c@'omo GCC transforma ficheros fuente a un fichero ejecutable. La compilaci@'on es un proceso multi-fase involucrando varias herramientas, incluyendo el Compilador de GNU en s@'{@dotless{i}} (a trav@'es de los frontends @code{gcc} o @code{g++}), el Ensamblador de GNU @code{as}, y el Enlazador de GNU @code{ld}. El conjunto completo de herramientas usadas en el proceso de compilaci@'on es llamado @dfn{toolchain}. @menu * Una vista de los procesos de compilaci@'on:: * El preprocesador:: * El compilador:: * El ensamblador:: * El enlazador:: @end menu @node Una vista de los procesos de compilaci@'on @section Una vista de los procesos de compilaci@'on La secuencia de comandos ejecutados por una simple invocaci@'on de GCC consiste en las siguientes fases: @itemize @bullet @item preprocesamiento (expandir macros) @item compilaci@'on (desde c@'odigo fuente a lenguaje ensamblador) @item ensamblaje (desde lenguaje ensamblador a c@'odigo m@'aquina) @item enlace (crear el ejecutable final) @end itemize @noindent Como ejemplo, se examinar@'an estas fases de compilaci@'on individualmente usando el programa @dfn{Hola Mundo} @file{hola.es.c}: @example @verbatiminclude hola.es.c @end example @noindent N@'otese que no es necesario usar cualquiera de los comandos individuales descritos en esta secci@'on para compilar un programa. Todos los comandos son ejecutados de manera autom@'atica y transparente por GCC internamente, y puede ser visto usando la opci@'on @option{-v} descrita antes (@pxref{Compilaci@'on verbosa}). El prop@'osito de este cap@'{@dotless{i}}tulo es proporcionar un entendimiento de c@'omo el compilador funciona. Aunque el programa @dfn{Hola Mundo} es muy simple, @'este usa cabeceras externas y librer@'{@dotless{i}}as, y as@'{@dotless{i}} ejercita todos los pasos importantes del proceso de compilaci@'on. @node El preprocesador @section El preprocesador @cindex preprocesador, primera etapa de compilaci@'on La primera fase del proceso de compilaci@'on es el uso del preprocesador para expandir macros y ficheros de cabecera incluidos. Para realizar esta fase, GCC ejecuta el siguiente comando:@footnote{Como se mencion@'o antes, el preprocesador est@'a integrado en el compilador en versiones recientes de GCC. Conceptualmente, el proceso de compilaci@'on es el mismo que ejecutar el preprocesar como una aplicaci@'on separada.} @cindex @code{.i}, extensi@'on de archivo preprocesado para C @cindex @code{i}, extensi@'on de archivo preprocesado para C @cindex extensi@'on, archivo preprocesado @code{.i} @cindex extensi@'on de archivo, archivo preprocesado @code{.i} @cindex @code{.ii}, extensi@'on de archivo preprocesado para C++ @cindex @code{ii}, extensi@'on de archivo preprocesado para C++ @cindex extensi@'on, archivo preprocesado @code{.ii} @cindex extensi@'on de archivo, archivo preprocesado @code{.ii} @example $ cpp hola.es.c > hola.i @end example @noindent El resultado es un fichero @file{hola.i} que contiene el c@'odigo fuente con todas las macros expandidas. Por convenci@'on, ficheros preprocesados son dados por la extensi@'on de fichero @file{.i} para programas C y @file{.ii} para programas C++. En la pr@'actica, el fichero preprocesado no es guardado en disco a menos que la opci@'on @option{-save-temps} sea usada. @node El compilador @section El compilador @cindex compilar, convertir c@'odigo fuente a c@'odigo ensamblador @cindex @option{-S}, opci@'on crear c@'odigo ensamblador @cindex @option{S}, opci@'on para crear c@'odigo ensamblador La siguiente fase del proceso es compilaci@'on de c@'odigo fuente preprocesado a lenguaje ensamblador, para un procesador espec@'{@dotless{i}}fico. La opci@'on @option{-S} dicta a @code{gcc} a convertir el c@'odigo fuente C a lenguaje ensamblador sin crear un fichero objeto: @example $ gcc -Wall -S hola.i @end example @noindent @cindex @code{.s}, extensi@'on de archivo ensamblador @cindex @code{s}, extensi@'on de archivo ensamblador @cindex extensi@'on, archivo ensamblador @code{.s} @cindex extensi@'on de archivo, archivo ensamblador @code{.s} El lenguaje ensamblador resultante es almacenado en el fichero @file{hola.s}. Aqu@'{@dotless{i}} est@'a el lenguaje ensamblador de @dfn{Hola Mundo} para un procesador Intel x86 (i686): @example $ cat hello.s .file "hello.c" .section .rodata .LC0: .string "Hello, world!" .text .globl main .type main, @@function main: .LFB0: .cfi_startproc pushl %ebp .cfi_def_cfa_offset 8 .cfi_offset 5, -8 movl %esp, %ebp .cfi_def_cfa_register 5 andl $-16, %esp subl $16, %esp movl $.LC0, (%esp) call puts movl $0, %eax leave .cfi_restore 5 .cfi_def_cfa 4, 4 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Debian 4.6.1-4) 4.6.1" .section .note.GNU-stack,"",@@progbits @end example @noindent N@'otese que el lenguaje ensamblador contiene una llamada a la funci@'on externa @code{puts}, una versi@'on simple de @code{printf} para cadenas que no contienen caracteres formateados. @node El ensamblador @section El ensamblador @cindex ensamblador, convirtiendo lenguaje ensamblador en c@'odigo m@'aquina El prop@'osito de un ensamblador es convertir lenguaje ensamblador a c@'odigo m@'aquina y generar un fichero objeto. Cuando hay llamadas a funciones externas en el fichero fuente de ensamblador, el ensamblador deja las direcciones las funciones externas indefinidas, para ser rellenadas despu@'es por el enlazador. El ensamblador puede ser invocado con la siguiente l@'{@dotless{i}}nea de comandos: @example $ as hola.s -o hola.o @end example @noindent As with GCC, the output file is specified with the @option{-o} option. The resulting file @file{hello.o} contains the machine instructions for the @dfn{Hello World} program, with an undefined reference to @code{puts}. @node El enlazador @section El enlazador @cindex enlazador, @code{ld} La fase final de compilaci@'on es el enlace de ficheros objeto para crear un ejecutable. En la pr@'actica, un ejecutable requiere muchas funciones externas del sistema y de librer@'{@dotless{i}}as C. Por consiguiente, los comandos de enlace actuales usados internamente por GCC son complicados. Por ejemplo, el comando completo para enlazar el programa @dfn{Hola Mundo} es:@footnote{El comando preciso var@'{@dotless{i}}a dependiendo de la versi@'on de @code{gcc} y el sistema operativo. Versiones recientes de @code{gcc} usan wrapper llamado @code{collect2} que hace alg@'un trabajo adicional antes de llamar a @code{ld}.} @example $ ld -dynamic-linker /lib/ld-linux.so.2 \ /usr/lib/crt1.o \ /usr/lib/crti.o \ /usr/lib/gcc/i486-linux-gnu/4.3/crtbegin.o \ -L/usr/lib/gcc/i486-linux-gnu/4.3 hola.o \ -lgcc -lgcc_eh \ -lc /usr/lib/gcc/i486-linux-gnu/4.3/crtend.o \ /usr/lib/crtn.o@end example @noindent Afortunadamente nunca se necesita escribir el comando de arriba directamente ---el proceso entero de enlace es manejado de manera transparente por @code{gcc} cuando se invoca como sigue: @example $ gcc hola.o @end example @noindent Esto enlaza el fichero objeto @file{hola.o} a la librer@'{@dotless{i}}a est@'andar de C, y produce un fichero ejecutable @file{a.out}: @example $ ./a.out @exclamdown{}Hola, mundo! @end example @noindent Un fichero objeto para un programa C++ puede ser enlazado a la librer@'{@dotless{i}}a est@'andar C++ del mismo modo con un simple comando @code{g++}. @node Examinado archivos compilados @chapter Examinado archivos compilados @cindex examinando archivos compilados @cindex archivos compilados, examinando Este cap@'{@dotless{i}}tulo describe varias herramientas comunes para examinar el contenido de los archivos objeto y ejecutables. @menu * Identificando archivos:: * Examinando la tabla de s@'{@dotless{i}}mbolos:: * Encontrando librer@'{@dotless{i}}as din@'amicas enlazadas:: @end menu @node Identificando archivos @section Identificando archivos @cindex comando @code{file}, para identificaci@'on de archivos @cindex identificaci@'on de archivos, con comando @code{file} @cindex archivo objeto, examinando con comando @code{file} @cindex ejecutable. examinando con comando @code{file} Cuando un archivo fuente ha sido compilado a un archivo objeto o a un ejecutable las opciones usadas en la compilaci@'on no son obvias. El comando @command{file} examina el contenido del archivo objeto o ejecutable y determina algunas de sus caracter@'{@dotless{i}}sticas, tal como si fu@'e compilado para enlazado est@'atico o din@'anico. Por ejemplo, aqu@'{@dotless{i}} se muestra el resultado del comando @command{file} para un ejecutable t@'{@dotless{i}}pico: @example $ file a.out a.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), not stripped @end example @noindent La salida muestra que el archivo ejecutable es enlazado con librer@'{@dotless{i}}as compartidas din@'amicamente, y compilado para procesadores Intel 386 y compatibles. Una completa explicaci@'on de la salida se muestra a continuaci@'on: @table @code @item ELF @cindex formato ELF @cindex formato COFF El formato interno de un archivo ejecutable (ELF proviene de ''Executable and Linking Format'', otros formatos como el COFF ``Common Object File Format'' fueron usados en antiguos sistemas operativos (p.e. MS-DOS)). @item 32 bits @cindex tama@~o de palabra, determinado desde el archivo ejecutable El tama@~no de palabra (para algunas plataformas esto ser@'{@dotless{i}}a 64 bits). @item LSB @cindex LSB, byte menos significativo (least significant byte) @cindex MSB, byte m@'as significativo (most significant byte) @cindex Motorola 680x0, ordenaci@'on de palabras @cindex ordenaci@'on de palabras, endianness @cindex endianness, ordenaci@'on de palabras @cindex big-endian, ordenaci@'on de palabras @cindex little-endian, ordenaci@'on de palabras Compilado para una plataforma con ordenaci@'on de palabras donde el primero es el byte menos significativo (LSB, @dfn{least significat byte}), tales como los procesadores Intel y AMD x86 (la alternativa el primero es el byte m@'as significativo (MSB, @dfn{most significant byte}) es usada en otros procesadores, tales como Motorola 680x0)@footnote{La ordenaci@'on MSB y LSB son conocidas como big-endian y little-endian respectivamente (el t@'ermino original es de la s@'atira ``Los viajes de Gulliver'' de Jonathan Swift's, de 1727).}. Algunos procesadores como Itanium y MIPS soportan ambas ordenaciones LSB y MSB. @item Intel 80386 Procesador para el cual ha sido complilado el archivo ejecutable. @item version 1 (SYSV) @cindex SYSV, formato de ejecutable en System V Esta es la versi@'on del formato interno del archivo. @item dynamically linked El ejecutable emplea librer@'{@dotless{i}}as compartidas din@'amicas (@code{statically linked} indicar@'{@dotless{i}}a que el programa fu@'e enlazado est@'aticamente, en el ejemplo usando la opci@'on @option{-static}) @item not stripped @cindex comando @code{strip} El ejecutable contiene una tabla de s@'{@dotless{i}}mbolos ( @'esta puede ser eliminada usando el comando @command{strip}). @end table @noindent El comando @command{file} puede ser usado con archivos objeto, donde dar@'a una salida similiar. El est@'andar POSIX@footnote{POSIX.1 (2003 edition), IEEE Std 1003.1.2003.} para sistemas Unix define el comportamiento del comando @command{file}. @node Examinando la tabla de s@'{@dotless{i}}mbolos @section Examinando la tabla de s@'{@dotless{i}}mbolos @cindex tabla de s@'{@dotless{i}}mbolos, examinando con @code{nm} @cindex comando @code{nm} Tal y como se describi@'o anteriormente en la discusi@'on sobre depuraci@'on, los archivos ejecutables y objeto pueden contener una tabla de s@'{@dotless{i}}mbolos (@pxref{Compilando para depuraci@'on}). Esta tabla almacena la localizaci@'on de las funciones y variables por nombre, y puede ser mostrada con el comando @command{nm}: @example $ nm a.out 08049534 d _DYNAMIC 08049608 d _GLOBAL_OFFSET_TABLE_ ........ 080483e4 T main U puts@@GLIBC_2.0 @end example @noindent Entre el contenido de la tabla de s@'{@dotless{i}}mbolos, la salida muestra que el inicio de la funci@'on @code{main} est@'a en el desplazamiento hexadecimal @code{080483e4}. La mayor@'{@dotless{i}}a de s@'{@dotless{i}}mbolos es para uso interno del compilador y del sistema operativo. Una @samp{T} en la segunda columna indica que esta funci@'on est@'a definida en el archivo objeto, mientras que una @samp{U} indica que esta funci@'on est@'a indefinida (y se deber@'a resolver en el enlazado con otro archivo objeto). Una completa explicaci@'on de la salida de @code{nm} se puede encontrar en la manual @cite{GNU Binutils}. @cindex Binutils, GNU Binary Tools El uso m@'as frecuente del comando @command{nm} es para comprobar si una librer@'{@dotless{i}}a contiene la definici@'on de una funci@'on espec@'{@dotless{i}}fica, observando las entradas @samp{T} en la segunda columna del nombre de la funci@'on. @node Encontrando librer@'{@dotless{i}}as din@'amicas enlazadas @section Encontrando librer@'{@dotless{i}}as din@'amicas enlazadas @cindex librer@'{@dotless{i}}as enlazadas din@'amicamente, examinando con @code{ldd} @cindex librer@'{@dotless{i}}as compartidas, examinado con @code{ldd} @cindex @code{ldd}, cargador din@'amico @cindex dependencias, de librer@'{@dotless{i}}as compartidas @cindex libre@'{@dotless{i}}as compartidas, dependencias @cindex librer@'{@dotless{i}}as, encontrando dependencias de librer@'{@dotless{i}}as compartidas Cuando un programa ha sido compilado usando librer@'{@dotless{i}}as compartidas necesita cargar estas librer@'{@dotless{i}}as din@'amicamente en tiempo de ejecuci@'on para realizar las llamadas a funciones externas. El comando @command{ldd} examina un ejecutable y muestra la lista de librer@'{@dotless{i}}as compartidas que necesita. Estas librer@'{@dotless{i}}as son referidas como librer@'{@dotless{i}}as compartidas @dfn{dependientes} del ejecutable. Por ejemplo, el siguiente comando muestra como se encuentra la librer@'{@dotless{i}}a compartida como dependencia del programa @dfn{Hola Mundo}: @example $ gcc -Wall hola.es.c $ ldd a.out libc.so.6 => /lib/libc.so.6 (0x40020000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)@end example @noindent La salida muestra que el programa @dfn{Hola Mundo} depende de la librar@'{@dotless{i}}a C @code{libc} (librer@'{@dotless{i}}a compartida versi@'on 6) y de la librer@'{@dotless{i}}a de carga din@'amica @code{ld-linux} (librer@'{@dotless{i}}a compartida versi@'on 2). Si el programa usa librer@'{@dotless{i}}as externas, tal como la librer@'{@dotless{i}}a matem@'atica, @'estas tambi@'en ser@'{@dotless{i}}an mostradas. Por ejemplo, el programa @code{calc} (el cual usa la funci@'on @code{sqrt}) genera la siguiente salida: @example $ gcc -Wall calc.es.c -lm -o calc $ ldd calc libm.so.6 => /lib/libm.so.6 (0x40020000) libc.so.6 => /lib/libc.so.6 (0x40041000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000) @end example @noindent La primera l@'{@dotless{i}}nea muestra que este programa depende de la librer@'{@dotless{i}}a matem@'atica @code{libm} (librer@'{@dotless{i}}a compartida veris@'on 6), adem@'as de las librer@'{@dotless{i}}a de C y la librer@'{@dotless{i}}a de carga din@'amica. El comando @code{ldd} puede ser usado para examinar estas mismas librer@'{@dotless{i}}as compartidas, con objeto de seguir la cadena de dependencia de librer@'{@dotless{i}}as compartidas. @node Mensajes comunes de error @chapter Mensajes comunes de error @cindex mensajes de error, ejemplos comunes @cindex mensajes comunes de error Este cap@'{@dotless{i}}tulo describe los errores y avisos m@'as frecuentes producidos por @code{gcc} y @code{g++}. Cada caso est@'a acompa@~nado por una descripci@'on de las causas, un ejemplo y sugerencias de posibles soluciones. N@'otese que los mensajes de error puede variar ligeramente entre las diferentes versiones del compilador. Algunos mensajes puede solo se mostrados con opciones tales @option{-Wall} y @option{-W}. @menu * Mensajes de error del preprocesador:: * Mensajes de error del compilador:: * Mensajes de error del enlazador:: * Mensajes de error en tiempo de ejecuci@'on:: @end menu @node Mensajes de error del preprocesador @section Mensajes de error del preprocesador @cindex Preprocesador, mensajes de error @table @code @item No such file or directory @cindex No such file or directory Este error ocurre si GCC no puede encontrar un fichero pedido en su ruta de b@'usqueda. El fichero puede haber sido especificado en la l@'{@dotless{i}}nea de comandos, o con una sentencia @code{#include}. Si el nombre del fichero ha sido tecleado incorrectamente o el directorio del fichero necesita ser a@~nadido para la ruta include o la ruta de enlace. Ejemplo: @example @verbatiminclude msg-file.es.c @end example @noindent El programa de arriba intenta incluir el fichero inexistente @file{stdoi.h} dando el error @samp{stdoi.h: No such file or directory}. El nombre de fichero correcto es @file{stdio.h}. @item macro or '#include' recursion too deep @itemx #include nested too deeply @cindex macro or '#include' recursion too deep @cindex include nested too deeply Este error ocurre si el preprocesador encuentra demasiadas directivas @samp{#include} anidadas. Esto es normalmente causado por dos @'o m@'as ficheros intentando incluir otro, provocando una recursi@'on infinita. Ejemplo: @example @verbatiminclude msg-nest1.es.h @end example @example @verbatiminclude msg-nest2.es.h @end example @noindent La soluci@'on a este problema es asegurar que los ficheros no se incluyen mutuamente, o usar `guardas include' (@pxref{Proporcionando sus propias plantillas} por ejemplo). @item invalid preprocessing directive #... @cindex directiva de preprocesamiento inv@'alida Este error indica que el preprocesador encontr@'o un comando @code{#} irreconocible. Ejemplo: @example @verbatiminclude msg-invalidpp.es.c @end example @noindent La sintaxis de preprocesador requiere @code{#elif} para la condici@'on ``else if'' en los bloques @code{#if}, en vez de @code{#elseif}. En el ejemplo de arriba ocurre un error de directiva inv@'alida en el incorrecto uso de @code{#elseif}, pero solo cuando @code{FOO} est@'a definido (en otros casos el preprocesador ignora cualquiera de la sentencia @code{#else}). @cindex @code{#elif}, directiva del precompilador @cindex @code{#else}, directiva del preprocesador @c @item warning: This file includes at least one deprecated or antiquated header. @c @cindex file includes at least one deprecated or antiquated header @c @cindex deprecated header in C++ @c @cindex antiquated header in C++ @c @cindex old-style C++ header files @c This warning is generated for C++ programs which include old-style @c library header files, such as @file{iostream.h}, instead of the modern @c C++ library headers without the @file{.h} extension. The old headers @c import their functions into the top-level global namespace, instead of @c using the @code{std::} namespace. Note that old-style header files are @c still supported, so this message is only a warning and existing programs @c will continue to compile. The message is actually generated by a @c @code{#warning} directive in the old header files, and not by the @c preprocessor itself. @c @cindex @code{#warning}, preprocessor directive @c Example: @c @example @c @verbatiminclude msg-cppheader.c @c @end example @c @noindent @c This program uses an old-style header file @file{iostream.h}. It could @c be updated to use @code{#include } and @code{std::cout} @c instead. @end table @node Mensajes de error del compilador @section Mensajes de error del compilador @cindex compilador, mensajes de error @table @code @item `@var{variable}' undeclared (first use in this function) @cindex variable no declarada En C y C++ las variables deben ser declaradas antes de poder ser usadas. Este mensaje de error indica que el compilador ha encontrado un nombre de variable que no tiene su declaraci@'on correspondiente. Esto puede ser causado por una declaraci@'on perdida, o por un error de escritura en el nombre. Los nombres de variables son sensibles a may@'usculas, as@'{@dotless{i}} @code{foo} y @code{Foo} representan diferentes variables. Para mantener breve la salida, s@'olo se informa del primer uso de una variable no declarada. Ejemplo: @example @verbatiminclude msg-undeclared.es.c @end example @noindent La variable @code{j} no est@'a declarada y saltar@'a el error @code{`j' undeclared}. @item parse error before `...' @itemx expected ';' before `...' @itemx syntax error @cindex parse error @cindex syntax error Este mensaje de error ocurre cuando el compilador encuentra una entrada inesperada, p.e. secuencias de caracteres que no siguen la sintaxis del lenguaje. Este mensaje de error salta por la ausencia de par@'entesis o llaves de cierre o punto y coma precediendo la l@'{@dotless{i}}nea de error, o una palabra reservada inv@'alida. Ejemplo: @example @verbatiminclude msg-parse.es.c @end example @noindent Aqu@'{@dotless{i}} hay una ausencia de punto y coma despu@'es de la primera llamada a @code{printf}, dando un @code{error de parseo}. @item parse error at end of input @itemx expected declaration or statement at end of input @cindex parse error at end of input Este error ocurre si el compilador encuentra un final de archivo inesperadamente, tal como cuando se analizan un n@'umero no balanceado de llaves de apertura y cierre. Es a menudo causado por la ausencia de un cierre de llaves en alg@'un lugar. Ejemplo: @example @verbatiminclude msg-eoi.es.c @end example @noindent Una llave de cierre adicional es necesaria en este programa para prevenir el error @code{expected declaration or statement at end of input}. @item warning: implicit declaration of function `...' @itemx warning: incompatible implicit declaration of built-in function `...' @cindex declaraci@'on impl@'{@dotless{i}}cita de funci@'on Este aviso es generado cuando una funci@'on es usada sin un prototipo declarado. Esto puede ser causado por la falta de inclusi@'on de una archivo de cabeceras, o si no olvidando suministrar un prototipo de funci@'on. Ejemplo: @example @verbatiminclude msg-implicitdecl.es.c @end example @noindent El archivo de cabeceras del sistema @file{stdio.h} no est@'a incluido, as@'{@dotless{i}} que el prototipo de la funci@'on @code{printf} no ha sido declarado. El programa necesita una l@'{@dotless{i}}nea inicial @code{#include }. @item unterminated string or character constant @itemx missing terminating " character @cindex unterminated string or character constant Este error es causado por unas comillas de apertura de una cadena o car@'acter que no tiene su correspondiente comillas de cierre. Las comillas deben aparecer en parejas coincidentes, como una comilla simple @code{'a'} para caracteres o dobles comillas @code{"aaa"} para cadenas. Ejemplo: @example @verbatiminclude msg-unterm.es.c @end example @noindent Las dobles comillas de apertura de la cadena en este programa no tiene su correspondiente dobles comillas de cierre, as@'{@dotless{i}} el compilador lee el resto del archivo como parte de la cadena. @item character constant too long @cindex character constant too long En C y C++ los caracteres son escritos usando simples comillas, p.e. @code{'a'} da el c@'odigo ASCII de la letra a (67), y @code{'\n'} da el c@'odigo ASCII de nueva l@'{@dotless{i}}nea (10). Este error ocurre si unas comillas simples son usadas para encerrar m@'as de un car@'acter. Ejemplo: @example @verbatiminclude msg-string2.es.c @end example @noindent El programa anterior confunde las comillas simples y dobles. Una secuencia de caracteres se debe escribir con comillas dobles, p.e. @code{"@exclamdown{}Hola Mundo!"}. Este mismo problema ocurre en el siguiente programa C++, @example @verbatiminclude msg-string2.es.cc @end example @noindent Este error puede ocurrir si la barra de divisi@'on y la barra invertida son confundidas en una secuencia de escape, p.e. usando @code{'/n'} en vez de @code{'\n'}. La secuencia @code{/n} consiste en dos caracteres separados, @samp{/} y @samp{n}. Observe que de acuerdo con el est@'andar C no hay l@'{@dotless{i}}mite en la longitud de una constante car@'acter, pero el valor de una constante car@'acter que contiene m@'as de un car@'acter est@'a definido en la implementaci@'on. Versiones m@'as recientes de GCC soportan constantes de car@'acter multi-byte, y en vez de avisar de un error @code{multiple-character character constant},ser@'a generado en este caso @code{warning: character constant too long for its type}. @cindex constante car@'acter multi-car@'acter @cindex character constant too long @item warning: initialization makes integer from pointer without a cast @cindex initialization makes integer from pointer without a cast Este error indica el uso err@'oneo de un puntero en un contexto entero. T@'ecnicamente, es posible convertir entre tipos punteros y enteros, pero es raramente necesario fuera de las aplicaciones a nivel de sistema. M@'as a menudo, este aviso es el resultado de usar un puntero sin desreferenciarlo (p.e. escribiendo @code{int i=p} en vez de @code{int i = *p}). Este aviso puede ocurrir con tipos @code{char} y @code{char *}, desde que @code{char} es un tipo entero. Ejemplo: @example @verbatiminclude msg-char.es.c @end example @noindent La variable @code{c} tiene tipo @code{char}, mientras que la cadena @code{'\n'} se evalua como un puntero a @code{const char *} (una zona de 2 bytes de memoria contiene el valor ASCII del car@'acter nueva l@'{@dotless{i}}nea seguido de un byte a cero @code{'\0'}, con el cual la cadena est@'a nul-terminada). El c@'odigo ASCII para el car@'acter nueva l@'{@dotless{i}}nea se puede encontrar usando @code{char c = '\n';} Errores similares pueden ocurrir con el uso incorrecto de la macro @code{NULL}, @example @verbatiminclude msg-null.es.c @end example @noindent En C, la macro @code{NULL} es definida como @code{((void *)0)} en @file{stdio.h} y solamente deber@'{@dotless{i}}a ser usada en un contexto de puntero. @c Note that it is important to distinguish between the ASCII character @c @sc{NUL} (character code 0) and the null pointer @code{NULL}. @c @example @c int i = 0; @r{zero} @c char c = '\0'; @r{null character, ASCII @sc{NUL}} @c char * s = ""; @r{empty string, a pointer to '\0'} @c void * p = NULL; @r{null pointer} @c @end example @item dereferencing pointer to incomplete type @cindex dereferencing pointer to incomplete type Este error ocurre cuando un programa intenta acceder a un elemento de una estructura a trav@'es de un puntero sin que la estructura haya sido declarada anteriormente. En C y C++ es posible declarar punteros a estructuras antes de la declaraci@'on de las estructuras, proporcionando los punteros que no son referenciados ---Esto es conocido como @dfn{declaraci@'on avanzada} (forward declaration). Ejemplo: @example @verbatiminclude msg-derefincomplete.es.c @end example @noindent Este programa tiene una declaraci@'on posterior de @code{data} como estructura @code{btree}. Sin embargo, la definici@'on de la estructura es necesaria antes de que el puntero pueda ser referenciado para acceder a sus miembros individualmente. @item warning: unknown escape sequence `...' @cindex unknown escape sequence Este error es causado por un incorrecto uso del car@'acter de escape en una cadena. Las secuencias de escape v@'alidas son: @multitable @columnfractions 0.12 .33 .33 @item @tab @code{\n} nueva l@'{@dotless{i}}nea @tab @code{\t} tabulador @item @tab @code{\b} retroceso @tab @code{\r} retorno de carro @item @tab @code{\f} alimentaci@'on de l@'{@dotless{i}}nea @tab @code{\v} tabulador vertical @item @tab @code{\a} alerta (campana) @end multitable @noindent Las combinaciones @code{\\}, @code{\'}, @code{\"} y @code{\?} pueden ser usadas para caracteres individuales. Las secuencias de escape pueden usar c@'odigos octales @code{\0}--@code{\377} y c@'odigos hexadecimales @code{\0x00}--@code{\0xFF}. Ejemplo: @example @verbatiminclude msg-unknownesc.es.c @end example @noindent La secuencia de escape @code{\N} en el programa anterior es inv@'alida ---La correcta secuencia de escape para el car@'acter de nueva l@'{@dotless{i}}nea es @code{\n}. @item warning: suggest parentheses around assignment used as truth value @cindex suggest parentheses around assignment used as truth value Este aviso resalta un potencial serio error, usando el operador @samp{=} en vez del operador de comparaci@'on @samp{==} en el test de la instrucci@'on condicional o en otra expresi@'on l@'ogica. Mientras el operador de asignaci@'on puede ser usado como parte de un valor l@'ogico, @'este es raramente el comportamiento deseado. Ejemplo: @example @verbatiminclude msg-assign.es.c @end example @noindent El test anterior deber@'{@dotless{i}}a haberse escrito como @code{if (i == 1)}, en otro caso la variable @code{i} ser@'a puesta a @code{1} por la evaluaci@'on de la misma instrucci@'on if. El operador @samp{=} tanto asigna como devuelve el valor de su parte derecha, causando que la variable @code{i} sea modificada y se tome una bifurcaci@'on inesperada. Similar resultado inesperado sucede con @code{if (i = 0)} en vez de @code{if (i == 0)}, excepto que en este caso el cuerpo de la instrucci@'on @code{if} nunca ser@'a ejecutado. Este aviso se suprime si la instrucci@'on es encerrada entre par@'entesis adicionales para indicar que est@'a siendo usado leg@'{@dotless{i}}timamente. @item warning: control reaches end of non-void function @cindex control reaches end of non-void function Una funci@'on que fu@'e declarada con un tipo de retorno, tal como @code{int} o @code{double}, debe tener siempre una instrucci@'on @code{return} devolviendo un valor del correspondiente tipo en todos los puntos de salida posibles ---en otro caso el valor de retorno no est@'a bien definido. Las funciones declaradas @code{void} no necesitan instrucciones @code{return}. Ejemplo: @example @verbatiminclude msg-control.es.c @end example @noindent El programa anterior alcanza el final de la funci@'on @code{display}, la cual retorna un tipo @code{int}, sin una instrucci@'on @code{return}. Una l@'{@dotless{i}}nea adicional como @code{return 0;} es necesaria. Cuando se usa @code{gcc} la funci@'on @code{main} de un programa C debe devolver un valor de tipo @code{int} (el estado de salida del programa). En C++ la instrucci@'on @code{return} puede ser omitida en la funci@'on @code{main} ---el valor de retorno de la funci@'on @code{main} por defecto es 0 si no es especificado. @item warning: unused variable `...' @itemx warning: unused parameter `...' @cindex aviso de variable no usada @cindex unused parameter warning Este aviso indica que una variable ha sido declarada como variable local o par@'ametro de una funci@'on, pero no ha sido usada en ning@'un lugar. Una variable no usada puede ser el resultado de un error de programaci@'on, tal como usar accidentalmente el nombre de una variable en vez de otro. Ejemplo: @example @verbatiminclude msg-unused.es.c @end example @noindent En este programa la variable @code{i} y el par@'ametro @code{p} nunca son usados. Observe que las variables no usadas son informadas por al opci@'on @option{-Wall}, mientras que los par@'ametros no usados s@'olo se muestran con @option{-Wall -W}. @item warning: passing arg of ... as ... due to prototype @cindex passing arg of function as another type to prototype Este aviso ocurrre cuando una funci@'on es llamada con un argumento de diferente tipo al especificado en su prototipo. La opci@'on @option{-Wconversion} es necesaria para habilitar estos avisos. Vea la descripci@'on de @option{-Wconversion} en @ref{Opciones de aviso adicionales} para ver un ejemplo. @item warning: assignment of read-only location @itemx warning: cast discards qualifiers from pointer target type @itemx warning: assignment discards qualifiers ... @itemx warning: initialization discards qualifiers ... @itemx warning: return discards qualifiers ... @cindex assignment of read-only location @cindex cast discards qualifiers from pointer target type @cindex assignment discards qualifiers @cindex initialization discards qualifiers @cindex return discards qualifiers Estos avisos ocurren cuando un puntero es usado de manera incorrecta, violando un calificador de tipo tal como @code{const}. Los datos accedidos a trav@'es de un puntero marcado como @code{const} no se modificar@'a, y el puntero en s@'{@dotless{i}} s@'olo puede ser asignado a otros punteros que tambi@'en son marcados como @code{const}. Ejemplo: @example @verbatiminclude msg-const.es.c @end example @noindent Este programa intenta modificar datos constantes, y descartar la propiedad @code{const} del argumento @code{s} en el valor devuelto. @item initializer element is not a constant @cindex initializer element is not a constant En C, las variables globales solo pueden ser inicializadas con constantes, tales como valores num@'ericos, @code{NULL} o cadenas. Este error ocurre si un valor no constante es usado. Ejemplo: @example @verbatiminclude msg-init.es.c @end example @noindent Este programa intenta inicializar dos variables desde otras variables. En particular, no se requiere al flujo @code{stdout} ser una constante por el est@'andar de C (aunque en algunos sistemas es una constante). N@'otese que inicializadore no constantes son permitidos en C++. @end table @node Mensajes de error del enlazador @section Mensajes de error del enlazador @cindex enlazador, mensajes de error @table @code @item file not recognized: File format not recognized @cindex file not recognized @cindex file format not recognized GCC usa la extensi@'on de un fichero, tal como @file{.c} o @file{.cc}, para determinar su contenido. Si no hay extensi@'on GCC no puede reconocer el tipo de fichero y dar@'a este error. Ejemplo: @example @verbatiminclude msg-ext @end example @noindent Si el programa de debajo est@'a guardado en un fichero @file{hola} sin extensi@'on, entonces al compilarlo dar@'a el siguiente error: @example $ gcc -Wall hola hola: file not recognized: File format not recognized collect2: ld returned 1 exit status@end example @noindent La soluci@'on es renombrar el fichero para la correcta extensi@'on, en este caso @file{hola.es.c}. @item undefined reference to `foo' @itemx collect2: ld returned 1 exit status @cindex error de referencia no definida @cindex collect2: ld returned 1 exit status @cindex ld returned 1 exit status Este error ocurre cuando un programa usa una funci@'on o variable que no est@'a definida en cualquiera de los ficheros objeto o librer@'{@dotless{i}}as suministradas para el enlazador. Esto puede ser causado por una librer@'{@dotless{i}}a perdida o el uso de un nombre incorrecto. En el mensaje de error de debajo, el programa @file{collect2} es parte del enlazador. Ejemplo: @example @verbatiminclude msg-undef.es.c @end example @noindent Si este programa est@'a compilado sin ser enlazado a una librer@'{@dotless{i}}a o fichero objeto conteniendo la funci@'on @code{foo()} habr@'a una indefinida referencia de error. @item /usr/lib/crt1.o(.text+0x18): undefined reference to `main' @cindex referencia indefinida a 'main' Este error es un caso especial del error de debajo, cuando la funci@'on perdida es @code{main}. En C y C++, cada programa debe tener una funci@'on @code{main} (d@'onde la ejecuci@'on comienza). Cuando se compila un fichero fuente individual sin una funci@'on @code{main}, usa la opci@'on @option{-c} (@pxref{Creando archivos objeto desde archivos fuente}). @end table @node Mensajes de error en tiempo de ejecuci@'on @section Mensajes de error en tiempo de ejecuci@'on @cindex Mensajes de error en tiempo de ejecuci@'on @table @code @item error while loading shared libraries: @itemx cannot open shared object file: No such file or directory @cindex error while loading shared libraries @cindex cannot open shared object file @cindex No such file or directory El programa usa librer@'{@dotless{i}}as compartidas, pero los necesarios ficheros de las librer@'{@dotless{i}}as compartidas no pueden ser encontrados por el enlazador din@'amico cuando el programa comienza. La ruta de b@'usqueda para las librer@'{@dotless{i}}as compartidas es controlada por la variable de entorno @env{LD_LIBRARY_PATH} (@pxref{Librer@'{@dotless{i}}as compartidas y librer@'{@dotless{i}}as est@'aticas}). @item Segmentation fault @itemx Bus error @cindex segmentation fault @cindex bus error @cindex puntero nulo @cindex puntero no inicializado @cindex @code{scanf}, aviso de uso incorrecto Estos mensajes en tiempo de ejecuci@'on indican un error de acceso a memoria Causas comunes incluyen: @itemize @bullet @item desreferenciando un puntero nulo o un puntero no inicializado @item acceso al array fuera de los l@'{@dotless{i}}mites @item incorrecto uso de @code{malloc}, @code{free} y funciones relacionadas @item uso de @code{scanf} con argumentos no v@'alidos @end itemize Hay una sutil diferencia entre fallos de segmentaci@'on y errores de bus. Un fallo de segmentaci@'on ocurre cuando un proceso intenta acceder a memoria protegida por el sistema operativo. Un error de bus ocurre cuando memoria v@'alida es accedida de un modo incorrecto (por ejemplo, intentando leer un @dfn{no alineado} valor en arquitecturas d@'onde los valores deben ser alineados con 4-bytes). @item floating point exception @cindex floating point exception Este error en tiempo de ejecuci@'on es causado por una excepci@'on aritm@'etica, tal como divisi@'on por cero, desbordamiento, por exceso y por defecto o una operaci@'on no v@'alida (p.e. la ra@'{@dotless{i}}z cuadrada de @math{-1}). El sistema operativo determina qu@'e condiciones producen este error. En sistemas GNU, las funciones @code{feenableexcept} y @code{fedisableexcept} pueden ser usadas para capturar o enmascarar cada tipo de excepci@'on. @item Illegal instruction @cindex error de instrucci@'on ilegal Este error es producido por el sistema operativo cuando se encuentra una instrucci@'on m@'aquina ilegal. Esto ocurre cuando el c@'odigo ha sido compilado para una arquitectura espec@'{@dotless{i}}fica y se ejecuta en otra. @end table @ignore @table @code @item function declaration isn't a prototype @item comparison between signed and unsigned @item too few arguments for format @item ... used with ... format @item declared inside parameter list @item may not appear in macro parameter list @item ? without following : @itemx : without preceding ? @itemx signed and unsigned type in conditional expression @item conflicting types for .... @item /* within comment @item type defaults to `int' in declaration of ... @item data definition has no type or storage class @item pointer targets differ in signedness @item storage size of ... isn't known @item integer overflow in expression @item no previous prototype for ... @item redundant redeclaration of ... @item array subscript has type char @item array subscript is not an integer @item cast from pointer to integer of different size @item return type defaults to int @item missing braces around initializer @item unterminated comment @item suggest explicit braces to avoid ambiguous else @item invalid lvalue in assignment @item function returns address of local variable @item comparison is always false due to limited range of datatype @itemx comparison is always true due to limited range of datatype puede ser causado por con signo versus sin signo@item excess elements in scalar initializer @item excess elements in struct initializer @item excess elements in array initializer @item invalid operands to binary ... @item return with a value in function returning void @item ... is a GCC extension @item empty body in an if-statement @item empty body in an else-statement @item invalid storage class for function ... @item unknown escape sequence ... @item variable or field ... declared void @item argument ... doesn't match prototype @item subscripted value is neither array nor pointer @item braces around scalar initializer @item number of arguments doesn't match prototype @item large integer implicitly truncated to unsigned type @item integer constant is too large for ... type @item overflow in implicit constant conversion @item nested extern declaration of ... @item parameter has incomplete type @item return with no value, in function returning non-void @item no return statement in function returning non-void @item this function may return with or without a value @item ... with different width due to prototype @item declaration of ... shadows a global declaration @item declaration of ... shadows a previous local declaration @item ... of read-only variable @item initializer element is not computable at load time @item empty character constant @item ... has an incomplete type @item integer constant is so large that it is unsigned @item backslash and newline separated by space @item array size missing in ... @item unrecognized format specifier ... @item ... as unsigned due to prototype @item ... as signed due to prototype @item overflow in constant expression @item floating point overflow in expression @item for loop initial declaration used outside C99 mode @item switch quantity is not an integer @item too many decimal points in number @item storage size of ... isn't constant @item as floating rather than integer due to prototype @item invalid conversion from ... to ... @item no matching function for call to ... @item shadow... @end table @end ignore @node Obteniendo ayuda @chapter Obteniendo ayuda @cindex obteniendo ayuda Si encuentras un problema no cubierto por esta introducci@'on, hay varios manuales de referencia que describen GCC y asuntos relacionados con el lenguaje en m@'as detalle (@pxref{Lectura adicional}). Estos manuales contienen respuestas a preguntas comunes, y un cuidadoso estudio de @'estas normalmente producir@'an una soluci@'on. De otro modo, hay muchas compa@~n@'{@dotless{i}}as y consultores quienes ofrecen soporte comercial para cuestiones de programaci@'on relativas a GCC por horas o de forma cont@'{@dotless{i}}nua. En los negocios esto puede ser un camino de costes efectivo para obtener soporte de alta calidad. @cindex comercial, soporte @cindex soporte comercial Un directorio de compa@~n@'{@dotless{i}}as que dan soporte al software libre y sus precios actualizados puede ser encontrado en el sitio web@footnote{@uref{http://www.gnu.org/prep/service.html}} del Proyecto GNU. Con software libre, el soporte comercial est@'a disponible en un mercado libre ---compa@~n@'{@dotless{i}}as de servicios compiten en calidad y precio, y los usuarios no est@'an atados a una determinada. En contraste, el soporte para el software privativo est@'a normalmente s@'olo disponible desde el vendedor original. @cindex mejoras de GCC Un soporte comercial de alto nivel para GCC est@'a disponible desde compa@~n@'{@dotless{i}}as involucradas en el desarrollo del conjunto de herramientas del compilador de GNU por s@'{@dotless{i}} mismo. Un listado de estas compa@~n@'{@dotless{i}}as puede ser encontrado en la secci@'on de ``Compa@~n@'{@dotless{i}}as de Desarrollo'' de la p@'agina web de la editorial para este libro.@footnote{@uref{http://www.network-theory.co.uk/gcc/intro/}} Estas compa@~n@'{@dotless{i}}as pueden proporcionar servicios tales como extender GCC para generar c@'odigo para nuevos procesadores o para arreglar errores encontrados en el compilador. @node Lectura adicional @unnumbered Lectura adicional @cindex manuales para software GNU La gu@'{@dotless{i}}a definitiva para GCC es el manual oficial de referencia, ``@cite{Using GCC}'', publicado por GNU Press: @cindex Usando GCC (Manual de Referencia) @cindex Compiladores GNU, Manual de Referencia @quotation @cite{Using GCC (for GCC version 3.3.1)} por Richard M. Stallman y the GCC Developer Community (Publicado por GNU Press, ISBN 1-882114-39-6) @end quotation @noindent Este manual es esencial para cualquiera que trabaje con GCC porque describe cada opci@'on en detalle. N@'otese que el manual est@'a actualizado cuando nuevas versiones de GCC llegan a estar disponibles, as@'{@dotless{i}} el n@'umero ISBN puede cambiar en el futuro. Si eres nuevo programando con GCC tambi@'en querr@'as aprender a usar el Depurador de GNU GDB, y a c@'omo compilar largos programas f@'acilmente con GNU Make. @'Estas herramientas son descritas en los siguientes manuales: @cindex Manual de GDB @cindex Manual de GNU Make @quotation @cite{Debugging with GDB: The GNU Source-Level Debugger} por Richard M. Stallman, Roland Pesch, Stan Shebs, et al. (Publicado por GNU Press, ISBN 1-882114-88-4) @end quotation @quotation @cite{GNU Make: A Program for Directing Recompilation} por Richard M. Stallman y Roland McGrath (Publicado por GNU Press, ISBN 1-882114-82-5) @end quotation @noindent Para una efectiva programaci@'on en C es tambi@'en esencial tener buenos conocimientos de la librer@'{@dotless{i}}a est@'andar de C. El siguientes manual documenta todas las funciones en la GNU C Library: @cindex Manual de Referencia de la GNU C Library @quotation @cite{The GNU C Library Reference Manual} por Sandra Loosemore con Richard M. Stallman, et al (2 vols) (Publicado por GNU Press, ISBN 1-882114-22-1 y 1-882114-24-8) @end quotation @noindent @cindex manuales GNU Press Aseg@'urate de visitar el sitio web @uref{http://www.gnupress.org/} para las @'ultimas ediciones impresas de manuales publicados por GNU Press. Los manuales pueden ser adquiridos online usando una tarjeta de cr@'edito en el sitio web de la FSF@footnote{@uref{http://order.fsf.org/}} adem@'as de estar disponbles para su compra a trav@'es de la mayor@'{@dotless{i}}a de las librer@'{@dotless{i}}as usando ISBN. Manuales publicados por GNU Press financian la Free Software Foundation y el Proyecto GNU. @cindex comillas en la shell Informaci@'on acerca de comandos de shell, variables de entorno y reglas de comillas en shell puede ser encontrada en el siguiente libro: @quotation @uref{http://www.network-theory.co.uk/bash/manual/,@cite{The GNU Bash Reference Manual},@cite{The GNU Bash Reference Manual}} por Chet Ramey y Brian Fox (Publicados por Network Theory Ltd, ISBN 0-9541617-7-7) @end quotation @noindent Otros Manuales de GNU mencionados en este libro (tal como @cite{GNU gprof ---The GNU Profiler} y @cite{The GNU Binutils Manual} no estaban disponibles en forma impresa en el momento en que este libro fu@'e a imprenta. Enlaces a copias online pueden ser encontradas en la p@'agina web de la editorial para esto book.@footnote{@uref{http://www.network-theory.co.uk/gcc/intro/}} La p@'agina web oficial del Proyecto GNU para GCC puede ser encontrado en @uref{http://www.gnu.org/software/gcc/}. @'Este sitio incluye una lista de preguntas frecuentes, as@'{@dotless{i}} como la base de datos de errores y gran cantidad de otra informaci@'on @'util acerca de GCC. Hay muchos libros acerca de los lenguajes C y C++. Dos de los est@'andares de referencia son: @cindex libros de referencia @cindex m@'as lectura acerca del lenguaje C @cindex libros, lectura adicional @cindex Kernighan and Ritchie, @cite{The C Programming Language} @quotation @cite{The C Programming Language} (ANSI edition) Brian W. Kernighan, Dennis Ritchie (ISBN 0-13110362-8) @end quotation @quotation @cite{The C++ Programming Language} (3rd edition) Bjarne Stroustrup (ISBN 0-20188954-4) @end quotation @noindent @cindex C library, standard @cindex est@'andares C, C++ y aritm@'etica del IEEE @cindex forma impresa del est@'andar de aritm@'etica del IEEE @cindex C y C++ est@'andares en forma impresa @cindex los est@'andares ISO para los lenguajes C y C++, disponibles como libros @cindex los est@'andares ANSI para los lenguajes C y C++, disponibles como libros Cualquiera usando los lenguajes C y C++ en un contexto profesional obtendr@'a una copia de los est@'andares oficiales, que est@'an disponibles como libros impresos: @quotation @cite{The C Standard: Incorporating Technical Corrigendum 1} (Publicado por Wiley, ISBN 0-470-84573-2) @end quotation @quotation @cite{The C++ Standard} (Publicado por Wiley, ISBN 0-470-84674-7) @end quotation @noindent Por referencia, el n@'umero est@'andar C es ISO/IEC 9899:1990, para el original est@'andar C publicado en 1990 e implementado por GCC. Un est@'andar de C revisado ISO/IEC 9899:1999 (conocido como C99) fu@'e publicado en 1999, y @'este es mayoritariamente (pero todav@'{@dotless{i}}a no completamente) soportado por GCC. El est@'andar de C++ es ISO/IEC 14882. @cindex est@'andar IEEE-754 El est@'andar de aritm@'etica en coma flotante IEEE-754 es importante para cualquier programa involucrados en computaci@'on num@'erica. El est@'andar est@'a disponible de manera comercial desde el IEEE, y tambi@'en es descrito en el siguiente libro: @quotation @cite{Numerical Computing with IEEE Floating Point Arithmetic} por Michael Overton (Publicado por SIAM, ISBN 0-89871-482-6). @end quotation @noindent El libro incluye muchos ejemplos para ilustrar la raz@'on fundamental para el est@'andar. @node Reconocimientos @unnumbered Reconocimientos Muchas personas han contribuido a este libro, y es importante recordar sus nombres aqu@'{@dotless{i}}: Gracias a Gerald Pfeifer, por su cuidadosa revisi@'on y numerosas sugerencias para mejorar el libro. Gracias a Andreas Jaeger, por la informaci@'on acerca de AMD64 y soporte multi-arquitectura, y sus muchos @'utiles comentarios. Gracias a David Edelsohn, por la informaci@'on acerca de la serie de procesadores POWER/PowerPC. Gracias a Jamie Lokier, por investigar. Gracias a Martin Leisner, Mario Pernici, Stephen Compall y Nigel Lowry, por sus @'utiles correcciones. Gracias a Gerard Jungman, por sus @'utiles comentarios. Gracias a Steven Rubin, por generar la imagen del chip para la cubierta con Electric. Y de manera m@'as importante, gracias a Richard Stallman, fundador del Proyecto GNU, por escribir GCC y hacer que sea software libre. @page @node Organizaciones de software libre @unnumbered Organizaciones de software libre El GCC, GNU Compiller Collection (Colecci@'on de Compiladores de GNU) es parte del Proyecto GNU, lanzado en 1984 para desarrollar un sistema operativo Unix completo que es software libre: el sistema GNU. La Free Software Foundation (FSF) es una organizaci@'on de caridad exenta de impuestos que recoge fondo para el continuo trabajo del Proyecto GNU. Est@'a dedicada a promover el derecho a usar, estudiar, copiar, modificar, y redistribuir programas de ordenador. Uno de los mejores caminos para ayudar al desarrollo del software libre es ser un miembro asociado a la Free Software Foundation, y pagar regularmente cuotas para dar soporte a sus esfuerzos. Los miembros asociados a la Free Software Foundation reciben muchos beneficios incluyendo noticias, admisi@'on a los encuentros anuales de la FSF, y descuentos en libros y CDROMs publicados por GNU Press. Los costes por ser miembro son deducibles de impuestos en Estados Unidos. Para m@'as informaci@'on acerca de c@'omo llegar a ser miembro visita el sitio web de la FSF en @uref{http://www.fsf.org/}. La Free Software Foundation Europe (FSFE) es una organizaci@'on hermana de la Free Software Foundation. La FSFE es activa en la promoci@'on del software libre a todos los niveles en Europa. Por una cuota anual, se puede ser miembro de la FSFE y dar soporte a su trabajo. Los miembros reciben una tarjeta de miembro personalizada y compatible con GPG, permitiendo autenticaci@'on digital segura de correo electr@'onico y ficheros, y obtener acceso a la ``FSFE Fellowship'', una comunidad electr@'onica por la libertad del software. Para m@'as informaci@'on, visita el sitio web de la FSFE en @uref{http://www.fsfe.org/}. La @cite{Foundation for a Free Information Infrastructure (FFII)} es otra organizaci@'on importante en Europa. FFII no se dedica espec@'ificamente al software libre, pero trabaja para defender los derechos de todos los programadores y usuarios de ordenadores contra los monopolios en el campo de la computaci@'on, tales como patentes de software. Para m@'as informaci@'on acerca de FFII, o para dar soporte a su trabajo con una donaci@'on, visita su sitio web en @uref{http://www.ffii.org/}. @ifnotinfo @node Licencia para documentaci@'on libre GNU @unnumbered Licencia para documentaci@'on libre GNU @center Version 1.2, November 2002 @smallerfonts @rm @display Copyright @copyright{} 2000,2001,2002 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @end display @enumerate 0 @item PREAMBLE The purpose of this License is to make a manual, textbook, or other functional and useful document @dfn{free} in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others. This License is a kind of ``copyleft'', which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software. We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference. @item APPLICABILITY AND DEFINITIONS This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The ``Document'', below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as ``you''. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law. A ``Modified Version'' of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language. A ``Secondary Section'' is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document's overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them. The ``Invariant Sections'' are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none. The ``Cover Texts'' are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words. A ``Transparent'' copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not ``Transparent'' is called ``Opaque''. Examples of suitable formats for Transparent copies include plain @sc{ascii} without markup, Texinfo input format, La@TeX{} input format, @acronym{SGML} or @acronym{XML} using a publicly available @acronym{DTD}, and standard-conforming simple @acronym{HTML}, PostScript or @acronym{PDF} designed for human modification. Examples of transparent image formats include @acronym{PNG}, @acronym{XCF} and @acronym{JPG}. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, @acronym{SGML} or @acronym{XML} for which the @acronym{DTD} and/or processing tools are not generally available, and the machine-generated @acronym{HTML}, PostScript or @acronym{PDF} produced by some word processors for output purposes only. The ``Title Page'' means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, ``Title Page'' means the text near the most prominent appearance of the work's title, preceding the beginning of the body of the text. A section ``Entitled XYZ'' means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as ``Acknowledgements'', ``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the Title'' of such a section when you modify the Document means that it remains a section ``Entitled XYZ'' according to this definition. The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License. @item VERBATIM COPYING You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3. You may also lend copies, under the same conditions stated above, and you may publicly display copies. @item COPYING IN QUANTITY If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document's license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects. If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages. If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public. It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document. @item MODIFICATIONS You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version: @enumerate A @item Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission. @item List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement. @item State on the Title page the name of the publisher of the Modified Version, as the publisher. @item Preserve all the copyright notices of the Document. @item Add an appropriate copyright notice for your modifications adjacent to the other copyright notices. @item Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below. @item Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document's license notice. @item Include an unaltered copy of this License. @item Preserve the section Entitled ``History'', Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled ``History'' in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence. @item Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the ``History'' section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission. @item For any section Entitled ``Acknowledgements'' or ``Dedications'', Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein. @item Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles. @item Delete any section Entitled ``Endorsements''. Such a section may not be included in the Modified Version. @item Do not retitle any existing section to be Entitled ``Endorsements'' or to conflict in title with any Invariant Section. @item Preserve any Warranty Disclaimers. @end enumerate If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version's license notice. These titles must be distinct from any other section titles. You may add a section Entitled ``Endorsements'', provided it contains nothing but endorsements of your Modified Version by various parties---for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard. You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one. The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version. @item COMBINING DOCUMENTS You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers. The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work. In the combination, you must combine any sections Entitled ``History'' in the various original documents, forming one section Entitled ``History''; likewise combine any sections Entitled ``Acknowledgements'', and any sections Entitled ``Dedications''. You must delete all sections Entitled ``Endorsements.'' @item COLLECTIONS OF DOCUMENTS You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects. You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document. @item AGGREGATION WITH INDEPENDENT WORKS A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an ``aggregate'' if the copyright resulting from the compilation is not used to limit the legal rights of the compilation's users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document. If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document's Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate. @item TRANSLATION Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail. If a section in the Document is Entitled ``Acknowledgements'', ``Dedications'', or ``History'', the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title. @item TERMINATION You may not copy, modify, sublicense, or distribute the Document except as expressly provided for under this License. Any other attempt to copy, modify, sublicense or distribute the Document is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. @item FUTURE REVISIONS OF THIS LICENSE The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See @uref{http://www.gnu.org/copyleft/}. Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License ``or any later version'' applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. @end enumerate @unnumberedsec ADDENDUM: How to use this License for your documents To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page: @smallexample @group Copyright (C) @var{year} @var{your name}. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A copy of the license is included in the section entitled ``GNU Free Documentation License''. @end group @end smallexample If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the ``with...Texts.'' line with this: @smallexample @group with the Invariant Sections being @var{list their titles}, with the Front-Cover Texts being @var{list}, and with the Back-Cover Texts being @var{list}. @end group @end smallexample If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation. If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software. @end ifnotinfo @node @'Indice @unnumbered @'Indice @printindex cp @ifset extrablankpages @comment final page must be blank for printed version @page @headings off @c @page @c @* @c @page @c @* @c @page @c @* @* @end ifset @bye