2010-06-23 11 views
9

Ich habe ein kleines Projekt, in dem ich zwei gleiche Namen Funktion in zwei verschiedenen Quelldateien genannt, aber während ich das Projekt erstellen, schlug der Compiler mit 'func_name bereits in filename.obj definiert'.Wie mit dem doppelten Funktionsnamen in C umzugehen?

Warum konnte ich nicht zwei Funktionen mit demselben Namen in zwei verschiedenen Quelldateien haben? Ich dachte, die Funktion sollte nur lokal für die Quelldatei sein, wenn sie in der Header-Datei deklariert wird, wird sie global.

Und gibt es außer der Änderung des Dateinamens noch eine andere elegante Lösung für den doppelten Funktionsnamen in der Programmiersprache C?

+0

Deshalb verwende ich immer wirklich aussagekräftige Namen für Variablen und Funktionen. Wenn diese beiden Funktionen genau dasselbe tun, dann brauchen Sie keinen von beiden. Wenn sie verschiedene Dinge tun, dann geben Sie jedem einen aussagekräftigen Namen, der widerspiegelt, was er tut. Wer Ihren Code pflegen muss, wird es Ihnen danken. Wahrscheinlichkeiten sind, das wirst du sein. – Mawg

Antwort

28

In C, eine Funktion standardmäßig globale Reichweite hat. Verwenden Sie das Schlüsselwort static, um den Gültigkeitsbereich des Moduls zu beschränken.

Die Rolle der Header-Datei besteht lediglich darin, die Funktion zusammen mit ihrer Signatur für andere Module zu veröffentlichen.

Alle globalen Namen müssen (mit einigen Vorbehalten) eindeutig sein. Dies ist sinnvoll, da dieser Name vom Linker verwendet wird, um einen Funktionsaufruf mit der Implementierung der Funktion selbst zu verbinden.

Namen mit statischem und lokalem Gültigkeitsbereich müssen nur innerhalb ihres Geltungsbereichs eindeutig sein.

+7

Hinweis: Markieren Sie jede Funktion als "statisch". Außerdem wird es dem Optimierer des Compilers erleichtert, beispielsweise Inline-Funktionen und ähnliches auszuwählen. – u0b34a0f6ae

2

Die elegante Lösung sind Namespaces, die in C++ eingeführt wurden. Die Lösung, wenn es wenige Aufrufe von func_name gibt, ist eine, nenne sie und kompiliere neu.

Etwas hackerous aber schnelle Lösung könnte sein:

//In one of the two source files and any file that calls it 

//if your functions is something like this 
//void func_name(int) { ... } 
//Add the following line 
#define func_name SOME_UNIQUE_FUNC_NAME 
+4

Statische ist die beste Lösung, wie von RBerteig vorgeschlagen. Ich lasse meine Antwort in der Hoffnung, dass es für jemanden irgendwie hilfreich sein könnte. – user347594

+0

war es hilfreich mit einem ähnlichen Problem, dem ich gegenüberstand. Vielen Dank. – FilipeCanatto

4

Deklarieren Sie die Funktion static, um sie lokal für die Datei zu machen. In C muss jeder Bezeichnername eindeutig sein.

5

Why could not I have two function with the same name in two differenct source file?

Becuase Linker muss wissen, welche gemeint ist, wenn man auf sie verweisen.

Imagaien, dass a.h und b.h beide defclare my_function(). Der Compiler generiert Code für beide. Stellen Sie sich nun vor, dass c.c Aufrufe my_function() - wie der Linker wissen, welche der beiden Versionen der Funktion aufgerufen werden soll?

5

Ob etwas in der Header-Datei oder in der Quelldatei deklariert wird, macht für den Compiler keinen Unterschied. Tatsächlich weiß der eigentliche Compiler absolut nichts über irgendwelche "Header-Dateien", da Header-Dateien von dem sogenannten Präprozessor, der seine Arbeit vor dem eigentlichen Compiler erledigt, in Quelldateien eingebettet werden. Zu dem Zeitpunkt, zu dem die Quelldateien (mit eingebetteten Header-Dateien) zum eigentlichen Compiler gelangen, gibt es keine Möglichkeit zu sagen, was ursprünglich dort war und was von Header-Dateien eingefügt wurde. Die Quelldatei mit allen eingebetteten Header-Dateien heißt Übersetzungseinheit. I.e. Der eigentliche Compiler arbeitet mit Übersetzungseinheiten, nicht mit einigen "source" - oder "header" -Dateien.

In C-Sprache haben alle Objekte und Funktionen, die im Dateibereich deklariert sind, standardmäßig externe Verknüpfung, was bedeutet, dass sie global sind, einzigartig für das gesamte Programm. Also hast du falsch gedacht. Funktionen sind nicht lokal für nur eine Quelldatei.

Wenn Sie eine Funktion (oder ein Objekt) lokal für eine einzelne Übersetzungseinheit erstellen möchten, müssen Sie einige explizite Schritte ausführen. Sie müssen es als static deklarieren. Wenn es als statisch deklariert wird, gibt es interne Verknüpfung, was im Wesentlichen bedeutet, dass es intern zu seiner Übersetzungseinheit wird.

Die Deklaration Ihrer Funktionen static funktioniert nur, wenn beide wirklich lokal in ihren eigenen Übersetzungseinheiten sein müssen. Wenn dies nicht der Fall ist, d. H. Wenn mindestens eine der Funktionen eine global zugängliche (verknüpfbare) Funktion sein sollte, dann haben Sie keine andere Wahl, als eine der Funktionen umzubenennen.

Verwandte Themen