¿Incluyendo un archivo fuente C en otro?

¿Está bien (o incluso recomendado / buena práctica) incluir #include .c archivo en otro archivo .c? ¿Qué sucede cuando están incluidos en un archivo de proyecto?

Utilizado correctamente, esta puede ser una técnica útil.

Supongamos que tiene un subsistema complejo y crítico para el rendimiento con una interfaz pública bastante pequeña y una gran cantidad de códigos de implementación no reutilizables. El código se ejecuta en varios miles de líneas, un centenar de funciones privadas y bastante información privada. Si trabaja con sistemas incrustados no triviales, es probable que trate esta situación con la frecuencia suficiente.

Su solución probablemente será en capas, modular y desacoplada, y estos aspectos se pueden representar y reforzar útilmente codificando diferentes partes del subsistema en diferentes archivos.

Con C, puede perder mucho al hacer esto. Casi todas las cadenas de herramientas ofrecen una optimización decente para una sola unidad de comstackción, pero son muy pesimistas sobre cualquier cosa declarada externamente.

Si pones todo en un módulo fuente C, obtienes –

  • Mejoras en el rendimiento y el tamaño del código: las llamadas a funciones se incluirán en muchos casos. Incluso sin incluir, el comstackdor tiene la oportunidad de producir un código más eficiente.

  • Datos de nivel de enlace y ocultación de funciones.

  • Evitar la contaminación del espacio de nombres y su corolario: puede usar nombres menos difíciles de manejar.

  • Comstackción y vinculación más rápida.

Pero también tienes un desastre profano cuando se trata de editar este archivo y pierdes la modularidad implícita. Esto puede superarse dividiendo la fuente en varios archivos e incluyéndolos para producir una sola unidad de comstackción.

Sin embargo, debe imponer algunas convenciones para administrar esto correctamente. Esto dependerá de su cadena de herramientas hasta cierto punto, pero algunos consejos generales son:

  • Coloque la interfaz pública en un archivo de encabezado separado; de todos modos, debería estar haciendo esto.

  • Tener un archivo .c principal que incluya todos los archivos .c subsidiarios. Esto también podría incluir el código para la interfaz pública.

  • Utilice guardias de comstackción para asegurarse de que los encabezados privados y los módulos de origen no estén incluidos en las unidades de comstackción externas.

  • Todos los datos y funciones privados deben declararse estáticos.

  • Mantener la distinción conceptual entre archivos .c y .h. Esto aprovecha las convenciones existentes. La diferencia es que tendrás muchas declaraciones estáticas en tus encabezados.

  • Si su cadena de herramientas no impone ninguna razón para no hacerlo, asigne un nombre a los archivos de implementación privados como .c y .h. Si usa incluir guardias, estos no producirán código y no introducirán nombres nuevos (puede terminar con algunos segmentos vacíos durante el enlace). La gran ventaja es que otras herramientas (por ejemplo, IDE) tratarán estos archivos de manera adecuada.

¿está bien? sí, comstackrá

es recomendado? Los archivos no – .c se comstackn en archivos .obj, que se vinculan entre sí después de la comstackción (por el vinculador) en el ejecutable (o biblioteca), por lo que no es necesario incluir un archivo .c en otro. Lo que probablemente quiera hacer en su lugar es crear un archivo .h que liste las funciones / variables disponibles en el otro archivo .c e incluya el archivo .h

No.

Dependiendo de su entorno de comstackción (no especifique), puede encontrar que funciona exactamente de la manera que desea.

Sin embargo, hay muchos entornos (tanto IDEs como muchos Makefiles hechos a mano) que esperan comstackr * .c: si eso sucede, probablemente termines con errores del enlazador debido a símbolos duplicados.

Como regla, esta práctica debe ser evitada.

Si debe #incluir el origen (y generalmente debe evitarse), use un sufijo de archivo diferente para el archivo.

Pensé que compartiría una situación en la que mi equipo decidió incluir archivos .c. Nuestra architecture consiste en gran parte en módulos que están desacoplados a través de un sistema de mensajes. Estos manejadores de mensajes son públicos y llaman a muchas funciones locales de trabajadores estáticos para hacer su trabajo. El problema surgió cuando intentamos obtener cobertura para nuestros casos de prueba unitaria, ya que la única forma de ejercer este código de implementación privada era indirectamente a través de la interfaz de mensajes públicos. Con algunas funciones de trabajador hasta la rodilla en la stack, esto resultó ser una pesadilla para lograr una cobertura adecuada.

La inclusión de los archivos .c nos dio una forma de llegar al engranaje en la máquina que estábamos interesados ​​en probar.

La extensión del archivo no es importante para la mayoría de los comstackdores de C, por lo que funcionará.

Sin embargo, dependiendo de su configuración de proyecto o archivo, el archivo c incluido podría generar un archivo de objeto separado. Al vincular eso, puede generar símbolos doblemente definidos.

Puede usar el comstackdor gcc en Linux para vincular dos archivos c en una salida. Supongamos que tiene dos archivos c uno es ‘main.c’ y otro es ‘support.c’. Entonces el comando para unir estos dos es

 gcc main.c support.c -o main.out 

De esta forma, dos archivos se vincularán a una única salida main.out Para ejecutar la salida, el comando será

 ./main.out 

Si está utilizando la función en main.c que se declara en el archivo support.c, debe declararla en main también utilizando la clase de almacenamiento extern.

El lenguaje C no prohíbe ese tipo de #include, pero la unidad de traducción resultante todavía tiene que ser válida C.

No sé qué progtwig está usando con un archivo .prj. Si está usando algo como “make” o Visual Studio o lo que sea, solo asegúrese de configurar su lista de archivos para comstackr sin la que no puede comstackr de forma independiente.

Puede incluir correctamente archivos .C o .CPP en otros archivos fuente. Dependiendo de su IDE, generalmente puede evitar la doble vinculación mirando las propiedades de los archivos fuente que desea incluir, generalmente haciendo clic derecho sobre ella y haciendo clic en Propiedades, y desmarcar / verificar comstackr / vincular / excluir de comstackción o cualquier otra opción tal vez. O no podría incluir el archivo en el proyecto en sí, por lo que el IDE ni siquiera sabrá que existe y no intentará comstackrlo. Y con makefiles, simplemente no pondría el archivo en él para comstackr y vincular.

EDITAR: Lo siento, lo hice una respuesta en lugar de una respuesta a otras respuestas 🙁

Incluir un archivo C en otro archivo es legal, pero no es aconsejable, a menos que sepa exactamente por qué lo hace y qué intenta lograr.
Estoy casi seguro de que si publicas aquí la razón detrás de tu pregunta, la comunidad te encontrará otra forma más apropiada de lograr tu objective (ten en cuenta el “casi”, ya que es posible que esta sea la solución dada el contexto )

Por cierto, me perdí la segunda parte de la pregunta. Si el archivo C se incluye en otro archivo y, al mismo tiempo, se incluye en el proyecto, probablemente terminará con un problema de símbolo duplicado por el que se vinculan los objetos, es decir, la misma función se definirá dos veces (a menos que sean estáticas).

deberías agregar un encabezado como este

 #include  

nota: ambos archivos deben colocarse en el mismo lugar