Een of meer meervoudig gedefinieerde symbolen gevonden

DebugUtil.h

#ifndef DEBUG_UTIL_H
#define DEBUG_UTIL_H
#include <windows.h>
int DebugMessage(const char* message)
{
    const int MAX_CHARS = 1023;
    static char s_buffer[MAX_CHARS+1];
    return 0;
}
#endif

Als ik dit probeer uit te voeren, krijg ik deze foutmelding:

Terrain.obj: fout LNK2005: “int
__cdecl DebugMessage(char const *)” (?DebugMessage@@YAHPBD@Z) al
gedefinieerd in Loodus.obj

Renderer.obj: fout LNK2005: “int
__cdecl DebugMessage(char const *)” (?DebugMessage@@YAHPBD@Z) al
gedefinieerd in Loodus.obj

test.obj: fout LNK2005: “int __cdecl
DebugMessage(char const *)”
(?DebugMessage@@YAHPBD@Z) al
gedefinieerd in Loodus.obj

C:\Users\Tiago\Desktop\Loodus
Engine\Debug\Loodus Engine.exe : fataal
fout LNK1169: een of meer vermenigvuldigen
gedefinieerde symbolen gevonden

Maar waarom gebeurt dit? Ik heb #ifndef #define en #endif in de header, dus meerdere definities zouden niet moeten voorkomen


Antwoord 1, autoriteit 100%

Zet de definitie (body) in een cpp-bestand en laat alleen de declaratie in een h-bestand. Inclusief bewakers werken alleen binnen één vertaaleenheid (ook wel bronbestand genoemd), niet in al uw programma’s.

De One Definition Rule van de C++-standaard stelt dat er precies één definitie zal verschijnen van elke niet-inline-functie die in het programma wordt gebruikt. Een ander alternatief zou dus zijn om je functie inline te maken.


Antwoord 2, autoriteit 19%

Maak de functie inline of declareer de functie in een headerbestand en definieer het in een cpp-bestand.

inline int DebugMessage(const char* message)
{
    const int MAX_CHARS = 1023;
    static char s_buffer[MAX_CHARS+1];
    return 0;
}

BEWERKEN:

Zoals een opmerking van Tomalak Geret’kal suggereert, is het beter om mijn laatste suggesties te gebruiken dan mijn eerste en de declaratie van de functie naar een cpp-bestand te verplaatsen.


Antwoord 3, autoriteit 12%

(Ervan uitgaande dat de geposte code een header is, opgenomen uit meerdere .cpp-bestanden)

Header guards beschermen je niet tegen meerdere link-time definities. Ongeacht het feit dat je ervoor hebt gezorgd dat de koptekst slechts één keer per vertaaleenheid verschijnt, als je meer dan één vertaaleenheid hebt, zijn dat nog steeds meerdere definities.

Schrijf definities in bronbestanden en alleen declaratiesin kopteksten.

De enige uitzonderingen zijn inline-functies, functies die zijn gedefinieerd binnen een class-definitie (hoewel dit niet wordt aanbevolen!) en functiesjablonen.


Antwoord 4, autoriteit 5%

Deze functie is opgenomen in elke vertaaleenheid en als resultaat krijg je er meerdere definities van – elk .obj-bestand bevat zijn eigen kopie. Wanneer het tijd is om ze allemaal aan elkaar te koppelen, toont de linker terecht de bovenstaande fout.

Je kunt een paar dingen doen:

  1. Verplaats de definitie naar een .cpp-bestand en bewaar alleen de declaratie in de koptekst.
  2. Gebruik een anonieme naamruimte rond de functie in je headerbestand (maar realiseer je dat het een hack is – je hebt nog steeds meerdere definities, alleen geen naambotsing).
  3. Markeer het als inline (hoewel het misschien niet altijd werkt – alleen als de compiler ervoor kiest om het inline te plaatsen). Dat is ook een hack om dezelfde reden als hierboven.

Antwoord 5

Verplaats de definitie naar een .cpp-bestand.


Antwoord 6

Verklaar uw functies in C++ -bestanden. Aangezien u uw functie in het kopbalbestand hebt gedefinieerd en dat koptekstbestand is opgenomen in meerdere bronbestanden, wordt deze gedefinieerd voor elk bronbestand dat het bevat. Daarom wordt het gemeld als op meerdere plaatsen gedefinieerd.

U kunt het alternatief inline maken, zodat de code wordt ingevoegd waar deze wordt gebruikt in plaats van elke keer als een afzonderlijke functie te worden gedefinieerd.


Antwoord 7

Het lijkt erop dat u debugutil.h in meer dan één vertaaleenheid inclusief die objecten bij elkaar lijmen. Debugutil.h biedt echter een definitie voor de debugmessage-functie, zodat die definitie bestaat in alle vertaaleenheden die de koptekst hebben opgenomen. Als gevolg hiervan, wanneer u de objecten koppelt, klaagt de linker terecht op dat het symbool vermenigvuldigt gedefinieerd.

Verander Debugutil.h, zodat het debugmessage via een prototype verklaart, maar geen definitie geeft en de definitie van debugmessage in een .c-bestand kan plaatsen dat u compileert en koppelt met uw andere objecten.


Antwoord 8

die alleen meerdere insluitsels in hetzelfde bronbestand voorkomt; Meerdere bronbestanden #includeING Het zal nog steeds meerdere definities van DebugMessage()genereren. In het algemeen moet u helemaal geen functies in kopbestanden plaatsen of deze maken static(en meestal inline, omdat het anders niet logisch is om meerdere staticdefinities van dezelfde functie).


Antwoord 9

100% Bepaalt u op de juiste manier bewakers, maar krijgt nog steeds opnieuw definiërende fout?

voor visuele studio:
Ik was echt gefrustreerd omdat ik correct was opgenomen bewakers,
Alleen om het probleem te achterhalen was Visual Studio. Als u het bestand hebt toegevoegd
aan uw project, zal de compiler het bestand twee keer toevoegen, zelfs als u
neem bewakers op rond uw implementatiebestand en headerbestand.

Als je niet uitsluitend Visual Studio gebruikt, en zeg… gebruik soms code::blocks, dan wil je misschien alleen #het bestand opnemen wanneer je merkt dat er geen visuele studio-omgeving is.

DebugUtil.h :
----------------------
#ifndef _WIN32
#include "DebugUtil.c"
#endif
----------------------

Als je het goed vindt om stdio.h op te nemen,
je kunt er wat minder huiverig voor zijn:

DebugUtil.h :
----------------------
#include <stdio.h>
#ifdef _MSC_VER
#include "DebugUtil.c"
#endif
----------------------

Referentie:
Voorgedefinieerde macro’s, Visual Studio:
https://msdn.microsoft.com/en-us/library/b0084kay. aspx

Other episodes