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.
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.
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.
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.
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.
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
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.
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.
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...
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...
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.
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.