webentwicklung-frage-antwort-db.com.de

Fehler "Mehrfachdefinition", "Hier zuerst definiert"

Ich habe 3 Projekte: Server, Client und Commons. Das Erstellen von Kopf- und Quellpaaren in Commons verursacht keine Probleme. Ich kann auf die Funktionen sowohl von Server als auch von Client frei zugreifen.

Aus irgendeinem Grund verursacht das Erstellen zusätzlicher Quell-/Header-Dateien im Server - oder Client -Projekt immer multiple definition of (...)- und first defined here-Fehler.

Beispiel:

command.h (im Stammverzeichnis des Client - Projekts)

#ifndef COMMANDS_H_
#define COMMANDS_H_

#include "commands.c"

void f123();

#endif /* COMMANDS_H_ */

command.c (im Stammverzeichnis des Client -Projekts)

void f123(){

}

main.c (im Stammverzeichnis des Client - Projekts)

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

}

Fehler:

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

Bereinigen, Neuerstellen des Index, Neuerstellen von Projekten hilft nicht. Der Computer wird auch nicht neu gestartet.

13
matt-pielat

Das Problem hierbei ist, dass Sie commands.c in commands.h vor dem Funktionsprototyp einfügen. Daher fügt der C-Vorprozessor den Inhalt von commands.c vor dem Funktionsprototyp in commands.h ein. commands.c enthält die Funktionsdefinition. Als Ergebnis endet die Funktionsdefinition vor der Funktionsdeklaration, die den Fehler verursacht.

Der Inhalt von commands.h nach der Vorprozessorphase sieht folgendermaßen aus:

#ifndef COMMANDS_H_
#define COMMANDS_H_

// function definition
void f123(){

}

// function declaration
void f123();

#endif /* COMMANDS_H_ */

Dies ist ein Fehler, da Sie eine Funktion nicht nach ihrer Definition in C deklarieren können. Wenn Sie #include "commands.c" und die Funktionsdeklaration ausgetauscht haben, sollte der Fehler nicht auftreten, da der Funktionsprototyp jetzt vor der Funktionsdeklaration steht. 

Das Einfügen einer .c-Datei ist jedoch eine schlechte Praxis und sollte vermieden werden. Eine bessere Lösung für dieses Problem wäre, commands.h in commands.c aufzunehmen und die kompilierte Version des Befehls mit der Hauptdatei zu verknüpfen. Zum Beispiel:

command.h

ifndef COMMANDS_H_
#define COMMANDS_H_

void f123(); // function declaration

#endif

command.c

#include "commands.h"

void f123(){} // function definition
16
Giuseppe Pes

Sie sollten nicht in Ihre Header-Datei Commands.c aufnehmen. Im Allgemeinen sollten Sie keine .c-Dateien einschließen. Befehl.c sollte vielmehr befehls.h enthalten. Wie hier definiert, fügt der C-Präprozessor den Inhalt von befehl.c in befehl.h ein, wo sich das Include befindet. Sie erhalten am Ende zwei Definitionen von f123 in befehl.h.

command.h

#ifndef COMMANDS_H_
#define COMMANDS_H_

void f123();

#endif

command.c

#include "commands.h"

void f123()
{
    /* code */
}
4
andrewrmack

Möglicherweise haben Sie die Datei .c mehrmals in das Makefile aufgenommen. 

1
Chuanhang.gu

Ich füge dieses A hinzu, weil ich mit einer bizarren Version davon erwischt wurde, bei der ich wirklich etwa eine Stunde lang am Kopf kratzte, bis ich die Ursache erkannte. Mein Ladevorgang schlug aufgrund mehrerer Wiederholungen dieses Formats fehl

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

Es stellte sich heraus, dass es sich bei meiner Makefile-Magie um einen Fehler handelte, bei dem ich eine Liste von C-Dateien und vpath usw. hatte, sodass die Kompilate sie aus dem richtigen Verzeichnis in der Hierarchie abrufen würden. Eine C-Datei wurde jedoch in der Liste wiederholt, am Ende einer Zeile und am Anfang der nächsten, sodass die von der Marke generierte gcc-Ladung die .o-Datei zweimal in der Befehlszeile hatte. Durrrrh Die mehrfachen Definitionen stammten von mehreren Vorkommen derselben Datei. Der Linker ignorierte Duplikate außer statischen Initialisierern! 

0
TerryE