“Meerdere Definitie”, “eerst gedefinieerd hier” Fouten

Ik heb 3 projecten: server , client en commons . Header & AMP maken; Bronparen in Commons veroorzaakt geen problemen en ik heb toegang tot de functies vrij van beide server en client .

Om een ​​of andere reden om extra bron / header-bestanden binnen -server of -client -project te maken, veroorzaakt u altijd multiple definition of (...)en first defined hereFouten.

Voorbeeld:

Commands.h (in root-dir van de Client -project)

#ifndef COMMANDS_H_
#define COMMANDS_H_
#include "commands.c"
void f123();
#endif /* COMMANDS_H_ */

Commands.c (in root-dir van de -client -project)

void f123(){
}

main.c (in root-dir van de client project)

#include "commands.h"
int main(int argc, char** argv){
}

Fouten:

make: *** [Client] Error 1      Client
first defined here              Client
multiple definition of `f123'   commands.c

Reiniging, wederopbouw-index, opnieuw opbouwen van projecten helpt niet. Noch herstart de computer.


Antwoord 1, Autoriteit 100%

Het probleem hier is dat je commands.copneemt in commands.hvóór het functie-prototype. Daarom voegt de C pre-processor de inhoud van commands.cin commands.hin vóór het functie-prototype. commands.cbevat de functiedefinitie. Als gevolg hiervan komt de functiedefinitie eerder te staan dan de functiedeclaratie die de fout veroorzaakt.

De inhoud van commands.hna de pre-processorfase ziet er als volgt uit:

#ifndef COMMANDS_H_
#define COMMANDS_H_
// function definition
void f123(){
}
// function declaration
void f123();
#endif /* COMMANDS_H_ */

Dit is een fout omdat je een functie niet kunt declareren na de definitie ervan in C. Als je #include "commands.c"en de functiedeclaratie hebt verwisseld, zou de fout niet moeten optreden omdat, nu komt het functie-prototype vóór de functiedeclaratie.

Het opnemen van een .c-bestand is echter een slechte gewoonteen moet worden vermeden. Een betere oplossing voor dit probleem zou zijn om commands.hop te nemen in commands.cen de gecompileerde versie van het commando aan het hoofdbestand te koppelen. Bijvoorbeeld:

commands.h

#ifndef COMMANDS_H_
#define COMMANDS_H_
void f123(); // function declaration
#endif

commands.c

#include "commands.h"
void f123(){} // function definition

Antwoord 2, autoriteit 11%

Je moet commands.c niet in je headerbestand opnemen. Over het algemeen moet u geen .c-bestanden opnemen. In plaats daarvan moet commands.c commands.h bevatten. Zoals hier gedefinieerd, voegt de C-preprocessor de inhoud van commands.c in commands.h waar de include is. Je krijgt uiteindelijk twee definities van f123 in commands.h.

commands.h

#ifndef COMMANDS_H_
#define COMMANDS_H_
void f123();
#endif

commands.c

#include "commands.h"
void f123()
{
    /* code */
}

Antwoord 3, autoriteit 11%

Ik had een soortgelijk probleem toen ik inlineniet gebruikte voor mijn algemene functie die op twee plaatsen was opgenomen.


Antwoord 4, autoriteit 8%

Misschien heb je het bestand .cmeerdere keren in makefile opgenomen.


Antwoord 5, autoriteit 3%

Ik voeg deze A toe omdat ik betrapt werd op een bizarre versie hiervan, waardoor ik echt ongeveer een uur lang mijn hoofd moest krabben totdat ik de oorzaak ontdekte. Mijn laden mislukte vanwege meerdere herhalingen van dit formaat

<path>/linit.o:(.rodata1.libs+0x50): multiple definition of `lua_lib_BASE'
<path>/linit.o:(.rodata1.libs+0x50): first defined here

Ik bleek een bug te zijn in mijn Makefile-magie waarbij ik een lijst met C-bestanden had en vpath enz. gebruikte, zodat de compilers ze uit de juiste map in de hiërarchie zouden halen. Eén C-bestand werd echter herhaald in de lijst, aan het einde van de ene regel en het begin van de volgende, dus de gcc-lading die door het merk werd gegenereerd, had het bestand .otwee keer op de opdrachtregel. Durrrr. De meerdere definities waren afkomstig uit meerdere gevallen van hetzelfde bestand. De linker negeerde duplicaten, afgezien van statische initialisatoren!

Other episodes