Definición múltiple de… error del enlazador

5 minutos de lectura

avatar de usuario
mazix

Definí un archivo especial: config.h

Mi proyecto también tiene archivos:

t.c, t.h
pp.c, pp.h
b.c b.h
l.cpp

y #incluye:

en tc:

    #include "t.h"
    #include "b.h"
    #include "pp.h"
    #include "config.h"

en ac:

    #include "b.h"
    #include "pp.h"

en ppc:

    #include "pp.h"
    #include "config.h"

en l.cpp:

    #include "pp.h"
    #include "t.h"
    #include "config.h"

no hay directivas include en mi *.h archivos, solo en *.c archivos Definí esto en config.h:

const char *names[i] =
        {
            "brian", "stefan", "steve"
        };

y necesito esa matriz en l.cpp, tc, pp.c pero recibo este error:

pp.o:(.data+0x0): multiple definition of `names'
l.o:(.data+0x0): first defined here
t.o:(.data+0x0): multiple definition of `names'
l.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status
make: *** https://stackoverflow.com/questions/17764661/multiple-definition-of-linker-error Error 1

He incluido guardias en cada *.h archivo que uso en mi proyecto. ¿Alguna ayuda para resolver esto?

  • posible duplicado del error del enlazador de definiciones múltiples después de agregar una función a un archivo previamente enlazado

    usuario529758

    20 de julio de 2013 a las 18:36

  • ¿Hay algún cambio reciente en Debian? Hasta hace unos días, mi proyecto se compilaba bien… Empecé a recibir este error (incluso para las revisiones que etiqueté y funcionaban bien hace unos días) después de actualizaciones recientes (estoy en pruebas de Debian).

    – cambio de marchas0

    15 de agosto de 2020 a las 4:04

avatar de usuario
yuhao

No defina variables en los encabezados. Coloque las declaraciones en el encabezado y las definiciones en uno de los archivos .c.

En config.h

extern const char *names[];

En algún archivo .c:

const char *names[] = { 
  "brian", "stefan", "steve" };

Si coloca una definición de una variable global en un archivo de encabezado, esta definición irá a cada archivo .c que incluya este encabezado, y obtendrá un error de definición múltiple porque una variable puede declararse varias veces pero solo puede definirse una vez .

Además, una cosa más que puede hacer si tiene que definir sus variables dentro de un archivo de encabezado, puede usar el static palabra clave.

static const char *names[] = {
  "brian", "stefan", "steve" };

Variable de esta manera names se definirá solo una vez en todo el programa y se podrá acceder a ella varias veces.

  • resuelto! 🙂 ¿Podría decirme por qué no debería poner declaraciones en h*. archivos?

    – mazix

    20/07/2013 a las 17:30

  • Así que no hará esto. Use archivos *.h solo para referenciar información. Debe recordar que “incluir” significa que incluye toda la información *.h en ese archivo, por lo que estaría copiando esa información (no solo la referencia) en cada archivo usando *.h. Esto puede confundir a los enlazadores, y lo hace.

    – Jiminion

    20 de julio de 2013 a las 17:34

  • @mazix No, el definición de una variable global debe ir al archivo .c, y poner el declaración en el encabezado. Recuerde que puede declarar una variable muchas veces pero definirla solo una vez.

    – YuHao

    20 de julio de 2013 a las 17:34

  • Solo para que la explicación sea un poco más clara, es probable que el archivo de encabezado se incluya en más de un archivo c, por lo que terminará con varias declaraciones de una variable con el mismo nombre.

    – Spalteer

    20 de julio de 2013 a las 18:17

  • es posible usar extern para constructor de clase?

    –Ebrahim Karimi

    27/10/2018 a las 20:07

Las declaraciones de funciones públicas van en los archivos de encabezado, sí, ¡pero las definiciones también son absolutamente válidas en los encabezados! Puede declarar la definición como estática (solo se permite 1 copia para todo el programa) si está definiendo cosas en un encabezado para funciones de utilidad que no desea tener que definir nuevamente en cada archivo c. IE define una enumeración y una función estática para traducir la enumeración a una cadena. Entonces no tendrá que volver a escribir la enumeración en el traductor de cadenas para cada archivo .c que incluya el encabezado. 🙂

  • De hecho, encuentro esta respuesta mucho más conveniente que la respuesta principal. Es más conveniente y atractivo tener un solo encabezado para almacenar todas las variables globales, por ejemplo, en lugar de tener archivos .h y .cpp. Gracias.

    – Saik

    28 de mayo de 2017 a las 2:25

  • También creo que esta solución es mejor que la más votada porque la otra necesita definir valores en cada archivo *.c, y además la tuya, @JonathanWhittenberg, se ve más elegante. Muchas gracias

    –Alejandro Galera

    3 de mayo de 2018 a las 8:59

  • Solución mejor y más elegante que el AA. +1 por agregar por qué no siempre es una mala idea.

    – SimonC

    8 de enero de 2019 a las 16:16

  • Esta no es una descripción precisa de lo que hace la estática. “Puede declarar la definición como estática (solo se permite 1 copia para todo el programa)” ¡NO! static hace que la definición se ajuste a esa unidad de compilación. Entonces te da una copia por compilar unidad. Entonces, si tiene una lista grande de cadenas, su programa terminará teniendo muchas copias duplicadas de esta lista… una para cada archivo c. Esto es aún peor para las funciones estáticas si luego va a depurar esto, porque ya no hay una sola función para colocar un punto de interrupción, sino muchas copias de esa función en el programa vinculado resultante.

    – Pingüino

    7 junio 2019 a las 23:20


Haga que sus definiciones sean estáticas en los archivos de encabezado.

  • Su respuesta podría mejorarse con información de apoyo adicional. Edite para agregar más detalles, como citas o documentación, para que otros puedan confirmar que su respuesta es correcta. Puede encontrar más información sobre cómo escribir buenas respuestas en el centro de ayuda.

    – Comunidad
    Bot

    7 de febrero a las 12:10

¿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