Compilar múltiples archivos C en un programa

4 minutos de lectura

avatar de usuario
María

Tengo los siguientes dos archivos:

archivo1.c

int main(){
  foo();
  return 0;
}

archivo2.c

void foo(){

 }

¿Puedo compilar y vincular los dos archivos para que el file1.c reconocerá el foo función sin agregar extern?

Actualizado el prototipo.

gcc archivo1.c archivo2.c arroja: advertencia: declaración implícita de la función foo.

  • gcc file1.c file2.ctampoco conozco las reglas exactas de C para las llamadas a funciones cuando no se ve un prototipo, pero es posible que deba agregar int foo(); encima main

    – Seth Carnegie

    4 de enero de 2012 a las 14:48


  • @Seth: por favor siempre -incluye -Wall al dar ejemplos de gcc, ayuda a que los novatos adquieran buenos hábitos.

    – Pablo R.

    4 de enero de 2012 a las 14:54

  • Actualicé la pregunta. Lo hago con -Wall.

    – María

    4 de enero de 2012 a las 14:55

avatar de usuario
Sangeeth Saravanaraj

La forma correcta es la siguiente:

file1.c

#include <stdio.h>
#include "file2.h"

int main(void){
    printf("%s:%s:%d \n", __FILE__, __FUNCTION__, __LINE__);
    foo();
    return 0;
}

file2.h

void foo(void);

file2.c

#include <stdio.h>
#include "file2.h"

void foo(void) {
    printf("%s:%s:%d \n", __FILE__, __func__, __LINE__);
    return;
}

output

$
$ gcc file1.c file2.c -o file -Wall
$
$ ./file 
file1.c:main:6 
file2.c:foo:6 
$ 

  • El identificador predefinido C99 es __func__. Prefiere esto al gcc específico __FUNCTION__.

    – pmg

    4 de enero de 2012 a las 15:18

  • No creo que sea una buena práctica pasar el encabezado al compilador de esa manera; si es necesario, el preprocesador lo traerá.

    – Timoteo Jones

    4 de enero de 2012 a las 15:18

  • @TimothyJones Mis disculpas. Ese es un buen punto. ¡Gracias por controlar la respuesta! .. ¡Ya lo he corregido!

    – Sangeeth Saravanaraj

    4 de enero de 2012 a las 15:22

  • Además, incluya siempre -Wall en cualquier ejemplo de línea de comando gcc.

    – Pablo R.

    4 de enero de 2012 a las 15:23

  • @Minuet: le dice al compilador que habilite todas las advertencias: las advertencias del compilador son realmente útiles e importantes, especialmente para las personas que aún están aprendiendo el idioma, pero desafortunadamente no están habilitadas de manera predeterminada. Compile siempre con las advertencias habilitadas y preste atención a las advertencias. que el compilador omite.

    – Pablo R.

    19 de noviembre de 2020 a las 15:31

avatar de usuario
chrisaycock

no necesitas un externpero file1.c debe ver una declaración que foo() existe Por lo general, esta declaración se encuentra en un archivo de encabezado.

Para agregar una declaración de reenvío sin usar un archivo de encabezado, simplemente modifique file1.c para:

int foo();  // add this declaration

int main(){
  foo();
  return 0;
}

  • ¿Puedo hacerlo sin ningún archivo de encabezado simplemente compilando los dos juntos?

    – María

    4 de enero de 2012 a las 14:56

  • Todavía necesita una declaración anticipada de foo()que podría hacer en file1.c si lo desea.

    – chrisaycock

    4 de enero de 2012 a las 14:58

  • @mary sí, los archivos de encabezado son para el compilador, pero esto lo hace el enlazador

    – Seth Carnegie

    4 de enero de 2012 a las 14:59

avatar de usuario
pablo r

latapero no deberías.

Use un archivo de encabezado, file2.h:

// file2.h

void foo(); // prototype for function foo()

Luego añade:

#include "file2.h" 

en archivo1.c

Compilar:

$ gcc -Wall file1.c file2.c -o foo

Como regla general, es mejor (más robusto) usar un archivo de encabezado para definir el interfaz de cada módulo en vez de ad hoc prototipos dentro de módulos dependientes. Esto a veces se conoce como el principio SPOT (Single Point Of Truth).

  • no necesitas extern para llamar a una función, solo necesita el prototipo, como int foo(); en el encabezado y el cuerpo en file2.c

    – Seth Carnegie

    04/01/2012 a las 15:00


  • @Seth: cierto, no lo haces necesitar pero no hay nada de malo en hacerlo explícito.

    – Pablo R.

    4 de enero de 2012 a las 15:02


  • Nunca he visto a nadie hacer una función. extern solo porque está en otro archivo. diciéndote puede pero no debe escribir una función en otro archivo sin usar extern en el prototipo es completamente infundado, a menos que sepa algo que yo no (lo cual es probable)

    – Seth Carnegie

    4 de enero de 2012 a las 15:04


  • @Seth: en absoluto, el prototipo es extern si lo declara explícitamente extern o usar las reglas implícitas de C. Lo puse allí para dejar claro a los novatos que es un prototipo, pero la mayoría de las personas no usan el explícito extern formulario de declaración en estos días.

    – Pablo R.

    4 de enero de 2012 a las 15:05


  • Entonces, ¿por qué le dices que no debe escribir una función que se utilizará en otros archivos sin escribir extern? La palabra “no debería” es demasiado fuerte aquí

    – Seth Carnegie

    4 de enero de 2012 a las 15:06


Es feo, pero usando gcc, podrías:

gcc -include file2.c file1.c

-include es una bandera para el preprocesador que incluirá el contenido de file2.c en la parte superior de file1.c. Habiendo dicho eso, es una mala elección y se descompone en todos los programas, excepto en los más simples.

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad