Vermeiden Sie mehrere definition durch die Aufnahme der gleichen header-Datei im Falle von mehreren Einheiten-Zusammenstellung
Habe ich eine Häufig verwendete Funktion f()
. Ich will f()
werden in der header-Datei util.h
, so dass ich verwenden können f()
einfach, ohne jede extra-Zusammenstellung:
user1.c
:
#include "util.h"
int main(){
f();
return 0;
}
util.h
:
void f(){
//do some job
}
Zusammenstellung von user1.c
:
gcc -o user1 user1.c
Das problem tritt auf, wenn es zwei compilation-units unit2.o
und unit3.o
. Ihre source-codes sind wie folgt:
user2.c
:
#include "util.h"
void user2_function(){
f();
//do other jobs
}
user3.c
:
#include "util.h"
extern void user2_function();
int main(){
f();
user2_function();
return 0;
}
Bekomme ich multiple definition of f
Fehler, wenn ich versuche zu kompilieren diese source-codes wie folgt:
gcc -c user2.c
gcc -c user3.c
gcc -o user user2.o user3.o
Frage ist, wie die multiple definition
problem gelöst werden kann? Oder gibt es bessere Lösungen?
In der realen Fall, es gibt Hunderte von Funktionen in util.h
und es gibt über 50 verschiedene compilation-units.
Ich versuche zu vermeiden, mit einer Bibliothek und die Zusammenstellung Schritt von utility-Funktionen da:
- Es gibt viele verschiedene Plattformen, die ich benutze.
- Ich Frage mich, ob es gibt eine einfache Lösung, D. H., ohne die Verwendung
cmake
usw. - Ich benutze auch cross-compilation für Coprozessoren.
- Ich will die flags, die in der Zusammenstellung der utility-Funktionen werden als flags benutzt, in der Zusammenstellung von Benutzer-codes.
- Wenn Sie möchten, um es in mehrere Dateien, entweder machen es statisch in die Kopf-oder erkläre es in der überschrift und definieren Sie es in Ihren eigenen Quellcode-Datei. Man versucht, die nicht-statische Funktion-definition vom header ist ... nicht gut zu funktionieren. Wie haben Sie herausgefunden, auf die harte Weise. Es gibt einen Grund, warum Funktionen wie
printf()
sind nicht definiert in<stdio.h>
; das ist es! - Gibt es irgendwelche reverse-Effekte mit
static
oderstatic inline
in Bezug auf die Laufzeit-performance, TLB miss Graf, instruction cache miss zählen, etc.? Zusammenstellung die Zeit ist nicht wichtig für mich. - Wenn es statisch ist, dann wird jede Datei, die enthält die header, bekommt eine Kopie von der Funktion, ob es benutzt wird oder nicht, so endet das Programm mit mehreren Kopien der code für die Funktion. Wenn Sie
static inline
, der code wird nur dann generiert, wenn Sie es verwenden. Es verschwendet Platz, also, und die Tatsache, dass, wenn es viel benutzt wird, Sie könnten am Ende benötigen, mehrere Kopien des gleichen Codes in den Speicher, eines für jede Datei, die aufgerufen wird, die erhöht die Wahrscheinlichkeit von cache-Anweisung findet. Das hinzufügen eines extra-object-Datei zu einem Programm mit mehreren ist es einfach. Verwenden eine Bibliothek, um es einfacher zu machen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Sind Sie eigentlich Angabe der Hauptteil der Funktion in der header-Datei. Daher Objekt-code ausgegeben wird für ihn in beiden Objekt-Dateien, die nicht zulässig bzw. gültig.
Um dies zu beheben, entweder:
inline
static
Arbeit?you then compile along with your other source code files
. Ich brauche ein einfach Lösung, da es viele Plattformen, cross-Kompilation, Flagge, Konsistenz, ...static
würde auch funktionieren, ja, aber es hätte eine andere Bedeutung/Wirkung. Diestatic
Funktion hätte eigentlich seinen Körper emittiert in beiden übersetzungseinheiten, aber der compiler/linker würde Magie benutzen, so dass es nicht tatsächlich zwei Definitionen. I. e. Sie würden zwei Kopien von der Funktion. Im Fall voninline
die Funktion ausgestoßen wird, in beide übersetzungseinheiten, aber der linker entfernt dann eine der Definitionen. I. e. Sie würde nur eine Kopie der Funktion.static
- Funktion in der Kopfzeile funktionieren würde, aber würde replizieren Sie den code in jede Objekt-Datei, die die header. Weiter, wenn eine Datei benötigt, die header, aber nicht die Funktion, würde die Funktion noch definiert werden (aber nicht genutzten, möglicherweise führen zu compiler-Warnungen). Einstatic inline
definition einer Funktion könnte besser arbeiten, wenn die Funktion klein genug fürinline
eine sinnvolle option — auch wenn der compiler einfach nicht inline, wenn es nicht sinnvoll ist.inline
hat nichts zu tun mit seiner Größe. Sie überschreiben nicht die compiler ist inlining Logik. Dieinline
Schlüsselwort bedeutet etwas ganz anderes.Ändern
util.h
zuutil.c
Durch ein neues
util.h
enthältstatt.