Forum: PC-Programmierung Anfänger: Funktionen überladen in C


von Sven (Gast)


Lesenswert?

Hallo

In Sprachen wie C++ oder C# können Funktionen ja überladen werden. Ist 
dies auch in (ANSI) C möglich?

Finde dazu in meinen Büchern nichts, wesshalb ich davon ausgehe, dass es 
wohl nicht möglich ist. Allerdings wird es auch in keinem Buch 
angesprochen, dass es nicht geht.

von yalu (Gast)


Lesenswert?

Nein.

von Sven (Gast)


Lesenswert?

Danke ;)
Dann hat sich das auch geklärt.

von Gerhard (Gast)


Lesenswert?

Hallo Sven
Hallo Yalu,

ja, eine Überladung in C ist möglich und geht das so,
dass ein Funktionsbezeichner der in den Objekts auftaucht NICHT mehr in 
den Libs gesucht wird.
Also zB schreibst du deine eigene Cosinus Funktion, referenzierst du 
diese UND andere Winkelfunktionen wie Sinus ..., bindest die mathlib 
(libm.a) mit -lm ein, DANN wird die Cosinus Funktion NICHT aus der 
Mathlib geholt, aber die anderen. Demnach hast du die Cosfunktion 
überladen.
Da der C-Linker keine Typenprüfung macht, kann das schwere Fehler 
verursachen. Da kannst Du mit einem globalen int eine lib-Funktion 
ausknipsen und dann gibt es einen Laufzeitfehler.
Die Überladung ist ein feature, kein bug, in C.

Hoffe es hilft, Gerhard.

von Karl H. (kbuchegg)


Lesenswert?

Unter Überladung einer Funktion versteht man aber normalerweise etwas 
anderes. Was du da beschreibst könnte man am ehesten noch als 
Function-Hiding bezeichnen.

Und das was du da beschreibst, ist kein Feature. Das ist definitiv ein 
Bug des Programmierers.

von Sven P. (Gast)


Lesenswert?

Gerhard schrieb:
> ja, eine Überladung in C ist möglich und geht das so,
> dass ein Funktionsbezeichner der in den Objekts auftaucht NICHT mehr in
> den Libs gesucht wird.
> Also zB schreibst du deine eigene Cosinus Funktion, referenzierst du
> diese UND andere Winkelfunktionen wie Sinus ..., bindest die mathlib
> (libm.a) mit -lm ein, DANN wird die Cosinus Funktion NICHT aus der
> Mathlib geholt, aber die anderen. Demnach hast du die Cosfunktion
> überladen.
Denkste? Denk ich nicht. Was machste denn mit den ursprünglichen 
Deklarationen in den Headern?
1
int printf() {
2
3
}
4
5
int main() {
6
  return 0;
7
}
1
test.c: In Funktion »printf«:
2
test.c:3: Fehler: Anzahl der Argumente passt nicht zum Prototypen
3
/usr/include/stdio.h:337: Fehler: Prototyp-Deklaration
4
test.c: In Funktion »main«:
5
test.c:8: Fehler: Zu wenige Argumente für Funktion »printf«

> Die Überladung ist ein feature, kein bug, in C.
C kennt keine Überladung und hat noch nie eine gekannt.
Eine ähnliche Funktionalität kann man mit Funktionszeigern erreichen, 
das wars dann aber auch wieder.

von Michael G. (linuxgeek) Benutzerseite


Lesenswert?

Karl heinz Buchegger schrieb:
> Unter Überladung einer Funktion versteht man aber normalerweise etwas
> anderes. Was du da beschreibst könnte man am ehesten noch als
> Function-Hiding bezeichnen.

Richtig, das hat bestenfalls etwas mit Namensraeumen zu tun, nicht mit 
Ueberladung, denn es darf im scope eben nur eine Funktion mit dem Namen 
geben. Ueberladung geht in C nicht, fertig aus.

von Freelancer (Gast)


Lesenswert?

und wie wird die überladung in c++ realisiert


void print(char c)         -->   print@@YAXD@Z
void print(int i)          -->   print@@YAXH@Z
void print(double x)       -->   print@@YAXN@Z
void print(const char *pc) -->   print@@YAXPBD@Z

für jedes print wird intern ein unterschiedliches aufgerufen

das sind intern immer unterschiedliche funktionen die aufgerufen werden

so kann man das dann auch nach c ableiten

von Karl H. (kbuchegg)


Lesenswert?

Michael G. schrieb:
> Karl heinz Buchegger schrieb:
>> Unter Überladung einer Funktion versteht man aber normalerweise etwas
>> anderes. Was du da beschreibst könnte man am ehesten noch als
>> Function-Hiding bezeichnen.
>
> Richtig, das hat bestenfalls etwas mit Namensraeumen zu tun, nicht mit
> Ueberladung, denn es darf im scope eben nur eine Funktion mit dem Namen
> geben.

Seh ich auch so.
Das beschriebene Verhalten ist IMHO eine klare Verletzung der 'One 
Definition Rule'.
Das einige Implementierungen sowas benutzen um zur Linkzeit speziell 
angepasste Versionen der Runtime Library zuzulinken spielt da keine 
Rolle. Die Implementierung eines Systems (also Compiler + Linker) hat 
wesentlich mehr Freiheiten als ein ordinärer Anwendungsprogrammierer.

von Karl H. (kbuchegg)


Lesenswert?

Freelancer schrieb:
> und wie wird die überladung in c++ realisiert

Aus der Tatsache, das momentane Compiler das so machen, darf man nicht 
schliessen, dass das so vorgeschrieben ist.
Sowohl der C als auch der C++ Standard halten sich fein säuberlich aus 
fast allem heraus was auch nur irgendwie in die Richtung geht: Wie 
implementiert ein Compiler ein bestimmtes Feature.

In keinem der beiden Standards wird dieses Name-Mangling gefordert, 
sondern das ist ein praktische Konsequenz aus den Möglichkeiten, die 
Linker zum Zeitpunkt des Erstellens des Systems hatten. Es wäre auch 
denkbar, dass alle Funktionen tatsächlich gleich heißen und der Linker 
beim Auflösen der Referenzen nicht nur den Funktionsnamen sondern auch 
die Argumentdatentypen berücksichtigt. Nichts im C++ Standard verhindert 
oder verbietet ein derartiges Vorgehen.

> das sind intern immer unterschiedliche funktionen die aufgerufen werden
> so kann man das dann auch nach c ableiten

Damit hat man dann aber immer noch kein Overloading. Overloading 
bedeutet, dass der Compiler aus einer Menge von möglichen Funktionen 
eine einzige, abhängig von den Argumentdatentypen auswählt. Das kann 
auch bedeuten, dass ich einen vorhandene Programmsequenz durch das 
hinzufügen einer weiteren Funktion in ihrer Funktionalität verändere, 
obwohl ich an der Programmsequenz selbst gar nichts verändert habe. Am 
Umstand, dass der Compiler die Auswahl der Funktion treffen muss, führt 
beim Overloading kein Weg vorbei.

von P. S. (Gast)


Lesenswert?

Wenn man sich einmal in den Tuecken von Funktionsueberladung verstrickt 
hat, lernt man auf diese Komfort zu verzichten. Zusammen mit 
Autokovertierung von Typen (speziell nach bool) und Default-Parametern 
kann man sich da ganz toll in den Fuss schiessen, weil man kaum noch 
nachvollziehen kann, welche Version eigentlich aufgerufen wird...

von Sven P. (Gast)


Lesenswert?

Freelancer schrieb:
> und wie wird die überladung in c++ realisiert
>
>
> void print(char c)         -->   print@@YAXD@Z
> void print(int i)          -->   print@@YAXH@Z
> void print(double x)       -->   print@@YAXN@Z
> void print(const char *pc) -->   print@@YAXPBD@Z
>
> für jedes print wird intern ein unterschiedliches aufgerufen
>
> das sind intern immer unterschiedliche funktionen die aufgerufen werden
>
> so kann man das dann auch nach c ableiten

Wie denn? Jedes mal von Hand den entsprechenden Funktionsnamen aufrugen? 
Klasse.
Das tolle und grausame am Überladen ist doch, dass sich der Compiler um 
genau das kümmert...

von Karl H. (kbuchegg)


Lesenswert?

Peter Stegemann schrieb:
> Wenn man sich einmal in den Tuecken von Funktionsueberladung verstrickt
> hat, lernt man auf diese Komfort zu verzichten. Zusammen mit
> Autokovertierung von Typen (speziell nach bool) und Default-Parametern
> kann man sich da ganz toll in den Fuss schiessen, weil man kaum noch
> nachvollziehen kann, welche Version eigentlich aufgerufen wird...

Füg ruhig noch eine Ladung Konstruktoren und Konvertier-Operatoren dazu 
und das Chaos ist perfekt.

Ich denke, da muss jeder mal durch. Erst wenn man selbst mal im 
Schlamassel steckt, weil man dem Compiler wieder mal einen Weg geöffnet 
hat einen eigentlich falschen Code doch noch zu übersetzen, benutzt man 
derartige Dinge mit mehr Vorsicht und Weitblick.

von Gerhard (Gast)


Lesenswert?

Hallo miteinander,
ich habe nicht den Anspruch der Meinungshoheit, hier ist die 
überwiegende Betrachtung aber von C++ aus, wie namespace, name-mangling 
und rules und schlechtem Progammierstil usw., ihr habt ja Recht.

Bleiben wir kurz mal beim "uralten" C Compiler Linker.
In 2004 ist mir in einem grossen embedded Projekt mit ca.500 
C-Quellfiles und von einer anderen Fa. zugelieferte lib sowas 
vorgekommen und ich habe sehr lange den Laufzeit Fehler gesucht.
Der Begriff function-hiding beschreibt den Effekt auch treffend,
der damalige Compiler Lieferant hatte diesen Effekt mit "overload" 
beschrieben.
Aber wie gesagt, der C-Compiler macht keine Typenprüfung und damit wurde 
mit der Deklaration eines globalen int eine lib Funktion nicht ins 
Codesegment eingebunden, ohne! warning und error Meldung, da schlugen 
die Wogen auch hoch. Beste Grüße an die Beitragschreibenden.

von Karl H. (kbuchegg)


Lesenswert?

Gerhard schrieb:

> Bleiben wir kurz mal beim "uralten" C Compiler Linker.
> In 2004 ist mir in einem grossen embedded Projekt mit ca.500
> C-Quellfiles und von einer anderen Fa. zugelieferte lib sowas
> vorgekommen und ich habe sehr lange den Laufzeit Fehler gesucht.
> Der Begriff function-hiding beschreibt den Effekt auch treffend,
> der damalige Compiler Lieferant hatte diesen Effekt mit "overload"
> beschrieben.

Glaub ich dir alles.
Das ist trotzdem kein Feature, sondern ein Bug. Nämlich die Verletzung 
einer fundamentalen Regel, die der Compiler/Linker nicht überprüfen 
können, und deren Überwachung und Einhaltung einzig der Sorgfaltspflicht 
des Programmierers unterliegt.
"In einem vollständigen Programm darf jedes Item nur einmal definiert 
aber beliebig oft deklariert werden, wobei alle Deklarationen sowie die 
Definition in ihrer Signatur vollständig übereinstimmen müssen"

Verletzt du diese Regel, hast du automatisch 'undefined behaviour' - 
Alles kann passieren. Egal ob man das jetzt undef.beh., overloading oder 
hiding nennt (Auch der Begriff Function Hiding ist in C++ bereits mit 
einer feststehenden Bedeutung besetzt)

Unter Funktionsüberladung versteht man aber ein Feature der Sprache, 
welches einem Programmierer zur freien Benutzung offen steht und 
sinnvoll eingesetzt werden kann.

Aus einem undefined behaviour-Bug kann aber niemals ein entsprechendes 
Feature werden, selbst wenn es in manchen Fällen auf genau das gleiche 
Verhalten hinausläuft.

Daher ist deine Anleitung hier
Beitrag "Re: Anfänger: Funktionen überladen in C"
als Anleitung zu "Wie begehe ich einen Fehler in C" zu verstehen und 
nicht als "Wie trickse ich ein Feature in die Sprache hinein, welches 
von den Sprachwächtern nicht vorgesehen ist"

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.