Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Guía completa de GCC

Instalación, configuración y uso del compilador GNU

Universidad Nacional de Rio Negro - Sede Andina

Introducción a GCC

GCC (GNU Compiler Collection, originalmente GNU C Compiler) es el compilador de código abierto más importante y ampliamente usado en el mundo. Desarrollado como parte del Proyecto GNU de la Free Software Foundation, GCC es el compilador estándar de facto en sistemas Unix y Linux.

¿Por qué usar GCC?

¿Cuándo usar GCC?

GCC es la elección ideal cuando:

GCC: Instalación y Compilación

GNU Compiler Collection (GCC) es una colección de compiladores que incluye soporte para C, C++, Objective-C, Fortran, Ada, Go y D, entre otros lenguajes.

Instalación del Compilador en Windows

Paso 1. Descargar el compilador:

Desde aquí

Paso 2. Descomprimir el archivo

Descomprimí el archivo ZIP para acceder al directorio mingw64. Hacé clic derecho sobre el archivo descargado y seleccioná la opción “Extraer aquí”.

Paso 3. Mover el directorio al disco C:

Sobre la carpeta mingw64 que acabás de extraer, hacé clic derecho y usá la opción “Mover a la carpeta” → Disco Local (C:) → Mover.

Mover carpeta mingw64

Proceso de movimiento de la carpeta

Ubicación final mingw64

Ubicación final en el disco C:

El resultado final debe ser la ruta C:\mingw64.

Paso 4. Configurar la variable de entorno PATH

Hacé clic derecho sobre “Este Equipo” en el Explorador de archivos.

Propiedades del sistema

Acceso a propiedades del sistema

Configuración del sistema

Ventana de configuración

Una vez allí, hacé clic en Configuración avanzada del sistema.

Configuración avanzada

Propiedades del sistema

Luego, hacé clic en “Variables de entorno”.

Variables de entorno

Acceso a variables de entorno

Ubicá la “Variable de Sistema” → PathEditar.

Ahí, usá el botón “Nuevo” y agregá la dirección C:\mingw64\bin (exactamente como está).

Agregar nueva ruta

Agregando la ruta del compilador

El resultado final debe verse así:

Configuración completa

Configuración completa


### Paso 5. Reiniciar la sesión

Cerrar sesión en Windows (o reiniciar el equipo).

:::{note}
En Windows 11, técnicamente no es necesario reiniciar.
gcc --version

Variable PATH configurada correctamente

Paso 6. Verificar la instalación

En una terminal (con las teclas WIN + R, escribí cmd y presioná Enter), ejecutá el comando:

Instalación en Linux

Ubuntu/Debian

# Actualizar índice de paquetes
sudo apt update

# Instalar GCC y herramientas de compilación esenciales
sudo apt install build-essential

# Esto instala:
# - gcc (compilador de C)
# - g++ (compilador de C++)
# - make (herramienta de automatización)
# - libc6-dev (bibliotecas de desarrollo de C)
# - dpkg-dev (herramientas de paquetes Debian)

# Verificar instalación
gcc --version
g++ --version
make --version

Instalación de versión específica:

# Ver versiones disponibles
apt-cache search gcc | grep '^gcc-[0-9]'

# Instalar versión específica (ejemplo: GCC 13)
sudo apt install gcc-13 g++-13

# Configurar alternativas para usar GCC 13 por defecto
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-13 100
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-13 100

# Verificar versión activa
gcc --version

Fedora/RHEL/CentOS

# Fedora
sudo dnf groupinstall "Development Tools"
sudo dnf install gcc gcc-c++

# RHEL/CentOS
sudo yum groupinstall "Development Tools"
sudo yum install gcc gcc-c++

# Verificar
gcc --version

Arch Linux

# Instalar grupo base-devel (incluye GCC, make, etc.)
sudo pacman -S base-devel

# Verificar
gcc --version

macOS

En macOS moderno, gcc es en realidad un alias a Clang. Para instalar GCC real:

# Instalar con Homebrew
brew install gcc

# Esto instala GCC con un número de versión (ej: gcc-13)
# Para usar GCC en lugar de Clang:
gcc-13 --version

# Crear alias (agregar a ~/.zshrc o ~/.bash_profile)
alias gcc='gcc-13'
alias g++='g++-13'

Visual Studio Code

Instalen desde Visual Studio Code el entorno.

Uso básico de GCC

Opciones fundamentales de compilación

GCC ofrece numerosas opciones para controlar el proceso de compilación. Aquí están las más importantes:

Warnings (advertencias)

Los warnings son mensajes que indican problemas potenciales sin detener la compilación.

# Warnings básicos (SIEMPRE usar)
gcc -Wall -Wextra ejercicio.c -o ejercicio

# Explicación de cada flag:
# -Wall: Habilita warnings comunes (pero no todos)
# -Wextra: Warnings adicionales no cubiertos por -Wall

# Warnings aún más estrictos (recomendado)
gcc -Wall -Wextra -Wpedantic ejercicio.c -o ejercicio
# -Wpedantic: Advierte sobre violaciones del estándar ISO C

# Tratar warnings como errores (útil en CI/CD)
gcc -Wall -Wextra -Werror ejercicio.c -o ejercicio
# -Werror: Convierte todos los warnings en errores de compilación

Warnings adicionales útiles:

# Conjunto completo de warnings recomendado
gcc -Wall -Wextra -Wpedantic \
    -Wformat=2 \           # Verificación estricta de printf/scanf
    -Wshadow \             # Variables que ocultan otras
    -Wconversion \         # Conversiones implícitas peligrosas
    -Wnull-dereference \   # Potenciales desreferencias de NULL
    -Wdouble-promotion \   # Promoción de float a double
    -Wundef \              # Uso de macros no definidas en #if
    ejercicio.c -o ejercicio

Niveles de optimización

GCC puede optimizar el código generado para hacerlo más rápido o más pequeño.

# Sin optimización (por defecto, mejor para debugging)
gcc -O0 ejercicio.c -o ejercicio

# Optimización básica (balance entre velocidad y tiempo de compilación)
gcc -O1 ejercicio.c -o ejercicio

# Optimización estándar (recomendado para producción)
gcc -O2 ejercicio.c -o ejercicio

# Optimización agresiva (puede aumentar tamaño del ejecutable)
gcc -O3 ejercicio.c -o ejercicio

# Optimizar para tamaño (útil en sistemas embebidos)
gcc -Os ejercicio.c -o ejercicio

# Optimización guiada por perfil (PGO - Profile Guided Optimization)
# Paso 1: Compilar con instrumentación
gcc -fprofile-generate ejercicio.c -o ejercicio
# Paso 2: Ejecutar el programa (genera datos de perfil)
./ejercicio
# Paso 3: Recompilar usando el perfil
gcc -fprofile-use ejercicio.c -o ejercicio

Información de debugging

# Información completa de debugging para GDB
gcc -g ejercicio.c -o ejercicio

# Debugging + sin optimizaciones (ideal para desarrollo)
gcc -g -O0 ejercicio.c -o ejercicio

# Nivel de información de debug específico
gcc -g3 ejercicio.c -o ejercicio  # Máxima información (incluye macros)

# Generar información de debug en formato DWARF específico
gcc -gdwarf-4 ejercicio.c -o ejercicio

Estándares de C

GCC soporta múltiples versiones del estándar C:

# C89/C90 (ANSI C - el más antiguo)
gcc -std=c89 ejercicio.c -o ejercicio
gcc -std=c90 ejercicio.c -o ejercicio  # Equivalente a c89

# C99 (agrega features como declaración de variables en for loops)
gcc -std=c99 ejercicio.c -o ejercicio

# C11 (agrega threads, atomic operations, etc.)
gcc -std=c11 ejercicio.c -o ejercicio

# C17/C18 (corrige defectos de C11, sin features nuevas)
gcc -std=c17 ejercicio.c -o ejercicio

# C23 (borrador del próximo estándar, soporte experimental)
gcc -std=c2x ejercicio.c -o ejercicio

# GNU extensions (extensiones de GCC sobre el estándar)
gcc -std=gnu11 ejercicio.c -o ejercicio  # C11 + extensiones GNU

Compilación modular

Para proyectos con múltiples archivos fuente:

# Estructura de ejemplo:
# main.c
# lista.c
# lista.h
# utils.c
# utils.h

# Opción 1: Compilar todo junto (simple, pero lento para proyectos grandes)
gcc -Wall -Wextra -std=c11 main.c lista.c utils.c -o programa

# Opción 2: Compilar por separado (más eficiente)
# Paso 1: Compilar cada .c a .o (archivo objeto)
gcc -Wall -Wextra -std=c11 -c main.c   # genera main.o
gcc -Wall -Wextra -std=c11 -c lista.c  # genera lista.o
gcc -Wall -Wextra -std=c11 -c utils.c  # genera utils.o

# Paso 2: Linkear todos los .o
gcc main.o lista.o utils.o -o programa

# Ventaja: Si modificás solo main.c, solo recompilás main.o
# Los otros .o no necesitan recompilarse

Con directorios de include:

# Si los .h están en un directorio separado
# Estructura:
# src/main.c
# src/lista.c
# include/lista.h
# include/utils.h

gcc -Wall -Wextra -std=c11 -Iinclude -c src/main.c
gcc -Wall -Wextra -std=c11 -Iinclude -c src/lista.c

# -I especifica directorios adicionales donde buscar .h

Linkeo con bibliotecas:

# Linkear biblioteca matemática (libm)
gcc programa.c -o programa -lm
# -l especifica biblioteca a linkear (m = libm.so o libm.a)

# Linkear múltiples bibliotecas
gcc programa.c -o programa -lm -lpthread

# Especificar directorios de bibliotecas
gcc programa.c -o programa -L/ruta/a/libs -lmilibreria
# -L especifica dónde buscar bibliotecas

Análisis estático con GCC

GCC incluye opciones de análisis estático que detectan bugs sin ejecutar el código:

# Análisis estático básico
gcc -fanalyzer ejercicio.c -o ejercicio

# Esto detecta:
# - Potenciales desreferencias de NULL
# - Use-after-free
# - Doble free
# - Memory leaks
# - Buffer overflows

# Ejemplo de uso completo
gcc -std=c11 -Wall -Wextra -fanalyzer -O2 -g ejercicio.c -o ejercicio

Generación de código ensamblador

Para aprender cómo funciona el código a bajo nivel:

# Generar archivo .s (ensamblador)
gcc -S ejercicio.c

# Generar con sintaxis AT&T (default)
gcc -S ejercicio.c -o ejercicio_att.s

# Generar con sintaxis Intel (más legible)
gcc -S -masm=intel ejercicio.c -o ejercicio_intel.s

# Ver código ensamblador con código C intercalado
gcc -Wa,-adhln -g ejercicio.c > ejercicio_mixed.s

Preprocesamiento

Ver el resultado después de que el preprocesador expande macros e includes:

# Solo preprocesar (genera archivo .i)
gcc -E ejercicio.c -o ejercicio.i

# Esto es útil para:
# - Debuggear problemas con #define
# - Ver qué incluye realmente un .h
# - Entender errores del preprocesador

Compilar con GCC

Considerá las siguientes líneas de código en un archivo llamado ejercicio1.c:

#include <stdio.h>

/*
 *  1. Hola Mundo
 *  Desarrollar un programa que muestre por STDOUT el mensaje "Hola Mundo C!".
 *  Indicar en un comentario la instrucción de compilación con GCC
 *  por línea de comandos.
 */


int main()
{
    printf("Hola Mundo C!\n");
    return 0;
}

Para compilar el código, ejecutá el siguiente comando:

gcc ejercicio1.c

Si la compilación es exitosa, se genera un archivo ejecutable nombrado por defecto como a.out. Para especificar un nombre personalizado al ejecutable, usá la opción -o. Por ejemplo, si querés que el ejecutable se llame ejercicio1:

gcc ejercicio1.c -o ejercicio1

Finalmente, para ejecutar el programa:

./ejercicio1

Salida esperada:

Hola Mundo C!

Opciones avanzadas de GCC

Arquitecturas y plataformas

GCC puede compilar para diferentes arquitecturas:

# Ver arquitectura actual
gcc -dumpmachine

# Compilar para 32 bits en sistema 64 bits
gcc -m32 programa.c -o programa32

# Compilar para arquitectura específica
gcc -march=native programa.c -o programa  # Optimizar para CPU actual
gcc -march=x86-64 programa.c -o programa
gcc -march=armv7 programa.c -o programa

# Cross-compilation (compilar para otra plataforma)
# Requiere cross-compiler instalado
arm-linux-gnueabi-gcc programa.c -o programa-arm

Seguridad y hardening

Opciones para hacer el código más seguro:

# Stack protection (detecta buffer overflows en stack)
gcc -fstack-protector-strong programa.c -o programa

# Position Independent Executable (PIE) - dificulta exploits
gcc -fPIE -pie programa.c -o programa

# Fortify source (verificaciones adicionales en funciones de biblioteca)
gcc -D_FORTIFY_SOURCE=2 -O2 programa.c -o programa

# Conjunto completo de flags de seguridad
gcc -Wall -Wextra -Werror \
    -fstack-protector-strong \
    -fPIE -pie \
    -D_FORTIFY_SOURCE=2 \
    -O2 \
    programa.c -o programa

Generación de dependencias

Útil para Makefiles automáticos:

# Generar dependencias de un archivo
gcc -MM main.c
# Output: main.o: main.c lista.h utils.h

# Generar archivo de dependencias
gcc -MM main.c > main.d

# Uso en Makefile:
# include $(SRC:.c=.d)

Estructura de Trabajo Recomendada

Esta no es una obligación, sino una guía de cómo organizar los archivos de trabajo. El objetivo es facilitarte la gestión de los trabajos prácticos y demás actividades de la cátedra.

Ubicación en la Computadora

Es muy recomendable que la ruta de trabajo no contenga espacios, ya que esto puede complicar el uso de las herramientas de compilación y debugging.

Ejemplos de Rutas Apropiadas

En Windows:

C:\Facultad\Programacion1
C:\Dev\P1
C:\Users\tu_usuario\uni\p1

En Linux/macOS:

/home/usuario/facultad/programacion1
/home/usuario/dev/p1
~/Universidad/P1

Ejemplos de Rutas No Recomendadas

Evitá estas estructuras:

❌ C:\Mis Documentos\Programación 1\Trabajos Prácticos
❌ C:\Users\Usuario Con Espacios\Desktop\TP 1
❌ /home/usuario/Mis Archivos/Programación/TP 1

Estructura de Carpetas Sugerida

Una organización clara te ayudará a mantener el trabajo ordenado a lo largo del cuatrimestre:

p1/
+-- guias/
|   +-- guia01/
|   |   +-- ejercicio01.c
|   |   +-- ejercicio02.c
|   |   +-- ejercicio03.c
|   +-- guia02/
|   |   +-- ejercicio01.c
|   |   +-- ejercicio02.c
|   +-- guia03/
|       +-- ejercicio01.c
+-- tps/
|   +-- tp1/
|   |   +-- main.c
|   |   +-- funciones.c
|   |   +-- funciones.h
|   |   +-- README.md
|   +-- tp2/
|       +-- main.c
+-- parciales/
|   +-- parcial1/
|   +-- parcial2/
+-- apuntes/
    +-- notas.md

Convenciones de Nombres

Para los archivos fuente en C, seguí estas convenciones:

Para ejercicios individuales:

ejercicio01.c
ejercicio02.c
ejercicio03.c

Para archivos de cabecera:

funciones.h
tipos.h
operaciones.h

Para archivos de implementación:

funciones.c
tipos.c
operaciones.c

Archivos Ejecutables

Al compilar, los ejecutables generados no deberían mezclarse con el código fuente. Podés seguir alguna de estas estrategias:

Opción 1: Usar un Prefijo

gcc ejercicio01.c -Wall -Wextra -o bin_ejercicio01

Opción 2: Carpeta de Binarios

guia01/
+-- src/
|   +-- ejercicio01.c
|   +-- ejercicio02.c
+-- bin/
    +-- ejercicio01
    +-- ejercicio02

Compilación con carpetas separadas:

gcc src/ejercicio01.c -Wall -Wextra -o bin/ejercicio01

Control de Versiones (Opcional pero Recomendado)

Si usás Git para versionar tu código, incluí un archivo .gitignore en la raíz del proyecto:

# Ejecutables
*.exe
*.out
a.out

# Archivos objeto
*.o
*.obj

# Carpeta de binarios
bin/
build/

# Archivos temporales
*.tmp
*.swp
*~

# Dependencias del sistema
.DS_Store
Thumbs.db

Ejemplo Práctico de Flujo de Trabajo

Supongamos que vas a trabajar en el ejercicio 5 de la guía 3:

  1. Navegá al directorio correspondiente:

    cd programacion1/guias/guia03
  2. Creá el archivo fuente:

    # En Windows (usando notepad o VSCode)
    code ejercicio05.c
    
    # En Linux (usando nano, vim o VSCode)
    nano ejercicio05.c
  3. Escribí tu código

  4. Compilá con las opciones recomendadas:

    gcc ejercicio05.c -Wall -Wextra -std=c11 -o ejercicio05
  5. Ejecutá el programa:

    # En Windows
    ejercicio05.exe
    
    # En Linux/macOS
    ./ejercicio05
  6. Iterá: Si hay errores, corregí y recompilá

Herramientas Complementarias

Además del compilador y un editor de texto, considerá estas herramientas:

HerramientaPropósitoComando Básico
GDBDebugger para Cgdb ./programa
ValgrindDetección de errores de memoriavalgrind ./programa
MakeAutomatización de compilaciónmake
GitControl de versionesgit status

Resumen de Buenas Prácticas

Aspecto

Recomendación

Ejemplo

Rutas

Sin espacios, simples

C:\Dev\P1

Nombres de archivos

Descriptivos, sin tildes

ejercicio01.c

Compilación

Con warnings habilitados

gcc -Wall -Wextra

Organización

Por guías/temas

guias/guia01/

Binarios

Separados del código

bin/ o prefijo bin_

Flags recomendados para diferentes situaciones

Para estudiantes (desarrollo y aprendizaje)

# Comando básico recomendado
gcc -Wall -Wextra -Wpedantic -std=c11 -g -O0 ejercicio.c -o ejercicio

# Explicación:
# -Wall -Wextra -Wpedantic: Todos los warnings importantes
# -std=c11: Usar estándar C11
# -g: Información de debugging para GDB
# -O0: Sin optimizaciones (mejor para debugging)

Crear alias útiles (agregar a ~/.bashrc en Linux o macOS):

# Alias para compilación rápida
alias gcc11='gcc -Wall -Wextra -Wpedantic -std=c11 -g -O0'

# Uso:
gcc11 ejercicio.c -o ejercicio

Para testing y validación

# Compilación estricta con análisis estático
gcc -Wall -Wextra -Wpedantic -Werror \
    -std=c11 -g -O0 \
    -fanalyzer \
    -fsanitize=address,undefined \
    ejercicio.c -o ejercicio

# Explicación adicional:
# -Werror: Warnings son errores (fuerza a corregirlos)
# -fanalyzer: Análisis estático
# -fsanitize=address,undefined: Detectores de bugs en runtime

Para producción/release

# Optimización y seguridad
gcc -Wall -Wextra -std=c11 \
    -O2 \
    -DNDEBUG \
    -fstack-protector-strong \
    -D_FORTIFY_SOURCE=2 \
    -fPIE -pie \
    programa.c -o programa

# Explicación:
# -O2: Optimización estándar
# -DNDEBUG: Desactiva assert()
# -fstack-protector-strong: Protección contra stack overflow
# -D_FORTIFY_SOURCE=2: Verificaciones extra de seguridad
# -fPIE -pie: Position Independent Executable

Comparación de compiladores: GCC vs Clang

Si bien esta guía se enfoca en GCC, es útil conocer las diferencias con Clang:

Cuándo preferir GCC:

Cuándo considerar Clang:

Troubleshooting: problemas comunes

GCC no se encuentra después de instalar

# Linux: verificar que esté en el PATH
which gcc
echo $PATH

# Si no está, agregarlo (ejemplo Ubuntu)
export PATH="/usr/bin:$PATH"

# Hacer permanente (agregar a ~/.bashrc)
echo 'export PATH="/usr/bin:$PATH"' >> ~/.bashrc
source ~/.bashrc

Error: “undefined reference to...”

# Olvidaste linkear una biblioteca
# ❌ gcc programa.c -o programa
# ✅ gcc programa.c -o programa -lm

# O falta un archivo .c
# ❌ gcc main.c -o programa  (falta lista.c)
# ✅ gcc main.c lista.c -o programa

Warning: implicit declaration of function

# Olvidaste incluir un .h
# Solución: agregar #include apropiado

# Ejemplo:
# ❌ int main() { printf("hola"); }
# ✅ #include <stdio.h>
#    int main() { printf("hola"); }

Segmentation fault (core dumped)

# Desreferenciar puntero NULL, buffer overflow, etc.
# Compilar con debugging y ejecutar en GDB

gcc -g -O0 programa.c -o programa
gdb ./programa
(gdb) run
# GDB mostrará exactamente dónde ocurrió el error

# O usar Valgrind
valgrind ./programa

Permission denied al ejecutar

# El archivo no tiene permisos de ejecución
chmod +x programa
./programa

# En Windows, asegurate que el nombre incluya .exe
gcc programa.c -o programa.exe
programa.exe

Recursos adicionales

Documentación oficial

Tutoriales y guías

Herramientas complementarias

Comunidad y soporte

Conclusión

GCC es una herramienta fundamental para cualquier programador de C:

Para estudiantes, dominar GCC significa:

$ gcc --version
gcc (Ubuntu 13.2.0-23ubuntu4) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.

$ echo "¡Listo para compilar con GCC!"
¡Listo para compilar con GCC!