Kürzlich habe ich gelernt, das GCC eine Extension hat um Funktionspointer zu vergleichen. In der Pointer Arithmetik werden Function-Pointer wie übliche char* Pointer behandelt. Ich fand das höchst bizarr. Fällt einem von euch ein Use-Case dafür ein?
Warum soll das nicht gehen? Übrigens kennt gcc auch einen unären &&-Operator und goto *<ptr auf void>
Thomas schrieb: > Warum soll das nicht gehen? ISO C verbietet eigentlich Zeigerarithmetik mit Funktionszeigern. Auch die Konvertierung zwischen Funktions- und Objektzeigern (inklusive void*) ist übrigens eigentlich nicht erlaubt. Außerdem ist Zeigerarithmetik nur innerhalb von Arrays erlaubt, und Arrays aus Funktionen gibt es nicht.
Klar, aber nichts hindert dich, den Funktionspointer in ein unsigned zu casten. Wozu auch immer. Und Vergleichen geht mit allem.
Thomas schrieb: > aber nichts hindert dich, den Funktionspointer in ein unsigned zu > casten Die aliasing rules hindern dich daran.
Ma W. schrieb: > Thomas schrieb: >> aber nichts hindert dich, den Funktionspointer in ein unsigned zu >> casten > > Die aliasing rules hindern dich daran. Mein Kollege hat immer einen Text ann der Wand hinter dem Schreibtisch: Lerne die Regeln - und brich sie.
Die einzig wirklich sinnvolle "Arithmetik", die man mit Funktionspointern anstellen kann, ist der Vergleich.
Rolf M. schrieb: > und Arrays aus > Funktionen gibt es nicht. Es gibt Arrays aus allem erdenklichen, nur die Phantasie des Programmierers setzt dem Grenzen.
Nils P. schrieb: > Ich fand das höchst bizarr. Fällt einem von euch ein Use-Case dafür ein? Als bizarres Beispiel: In einer gegebenen Implementierung kann einer Funktion f ein Name mit set(f,name) zugordnet werden. Die funktion get(f) liefert diesen Namen zurück. Die aktuelle Implementierung von get() durchsucht alle Tupel (f,name) in O(n). Es wird eine schneller Implementierung benötigt und der Compiler unterstützt die Erweiterung für einen "<" Operator. Dann könnte man bspw. eine B-Baum für eine schnellere Implementierung nutzen.
Mirko77, vielen Dank. Du hast recht und so bizarr ist es gar nicht. Eine Map Datenstruktur von was-auch-immer auf Funktionspointern macht Sinn, und ohne Vergleichsoperator ist da nichts zu machen. Danke!
PittyJ schrieb: > Lerne die Regeln - und brich sie. Ueblicherweise ein guter Spruch, aber nicht bei C seitdem die Grammatikanwaelte uebernommen haben. Rolf M. schrieb: > Arrays aus Funktionen gibt es nicht. Echt nicht? Aber Arrazys aus Funktionspointern schon, oder?
Dumdi D. schrieb: > Rolf M. schrieb: >> Arrays aus Funktionen gibt es nicht. > > Echt nicht? Aber Arrazys aus Funktionspointern schon, oder? Ja, aber eine Funktion und ein Zeiger auf eine Funktion sind eben nicht dasselbe:
1 | typedef void func(void); // Funktionstyp -> ok |
2 | |
3 | func *funcptrarr[3]; // Array von Funktionszeigern -> ok |
4 | func funcarr [3]; // Array von Funktionen -> Fehler |
Fehlermeldung beim GCC:
1 | error: declaration of ‘funcarr’ as array of functions |
Mikro 7. schrieb: > Die aktuelle Implementierung von get() durchsucht alle Tupel (f,name) in > O(n). Für sowas gibts Hash-Funktionen und Hash Maps. Damit bekommt man die Zugriffszeit auf O(1).
Bernd K. schrieb: > Rolf M. schrieb: >> und Arrays aus >> Funktionen gibt es nicht. > > Es gibt Arrays aus allem erdenklichen, In C nicht. > nur die Phantasie des Programmierers setzt dem Grenzen. Manchmal auch die Logik. Dumdi D. schrieb: > PittyJ schrieb: >> Lerne die Regeln - und brich sie. > > Ueblicherweise ein guter Spruch, aber nicht bei C seitdem die > Grammatikanwaelte uebernommen haben. Das hat weder speziell mit C, noch mit "Grammatikanwälten" zu tun. In der Programmierung ist es eigentlich nie eine gute Idee, an den Regeln der verwendeten Sprache vorbei zu programmieren. Deshalb ist es bei neueren Sprachen oft so, dass das gar nicht mehr möglich ist. C ist da sehr "liberal" und markiert solche Sachen nur als "undefined behaviour". In z.B. Java würdest du gleich einen Fehler vom Compiler oder zumindest eine Exception bekommen. > Rolf M. schrieb: >> Arrays aus Funktionen gibt es nicht. > > Echt nicht? Ja, echt nicht. > Aber Arrazys aus Funktionspointern schon, oder? Ja, die gibt es. Zeiger (egal worauf) sind Objekte, Funktionen sind keine Objekte.
Rufus Τ. F. schrieb: > Die einzig wirklich sinnvolle "Arithmetik", die man mit > Funktionspointern anstellen kann, ist der Vergleich. Ganz klares NEIN. Nur ein Beispiel: Funktionen für bestimmte Kombinationen von Bits irgendwelcher Eingangswerte zu wählen. Die weitaus schnellste Methode dafür ist, diese Funktionen über eine Tabelle von Funktionszeigern verfügbar zu machen und den Entry in diese Tabelle aus den Eingangsdaten zu BERECHNEN (naja: Shift entsprechend der Breite eine Funktionszeigers und Addition der Basisadresse der Tabelle, dann indirekter Unterprogrammaufruf) Du hast einfach wirklich keine Ahnung von garnix. Wer zum Teufel hat dich eigentlich zum Moderator gemacht?
c-hater schrieb: > Nur ein Beispiel: Funktionen für bestimmte Kombinationen von Bits > irgendwelcher Eingangswerte zu wählen. Die weitaus schnellste Methode > dafür ist, diese Funktionen über eine Tabelle von Funktionszeigern > verfügbar zu machen und den Entry in diese Tabelle aus den Eingangsdaten > zu BERECHNEN (naja: Shift entsprechend der Breite eine > Funktionszeigers und Addition der Basisadresse der Tabelle, dann > indirekter Unterprogrammaufruf) Au weia, was für ein Eigentor! Was hat denn die Berechnung eines Tabellenindex' mit Pointerarithmetik zu tun? Naja, da war der Name des lieben Kollegen mal wieder Programm... :-( Grüßle Volker
c-hater schrieb: > Du hast einfach wirklich keine Ahnung von garnix. Wie üblich mal wieder mit der Beleidigungs-Keule selbst ins Aus navigiert. Ärgerlich ist, dass du darüber hinaus leider nicht einmal verstanden hast, worum es überhaupt geht… c-hater schrieb: > Die weitaus schnellste Methode dafür ist, diese Funktionen über eine > Tabelle von Funktionszeigern verfügbar zu machen und den Entry in diese > Tabelle aus den Eingangsdaten zu BERECHNEN (naja: Shift entsprechend der > Breite eine Funktionszeigers und Addition der Basisadresse der Tabelle, > dann indirekter Unterprogrammaufruf) Sehr schön, und wo hast du jetzt mit dem Funktionszeiger gerechnet? Denn darum ging es. Nicht die Berechnung eines Index in einer Tabelle, sondern Arithmetik mit der Funktions-Adresse, die im Zeiger drin steht.
"Arithmetik" ist ein grosses Wort für Vergleich auf Gleichheit. Zumal nicht auf jeder Plattform ein einfacher bitweiser Vergleich ausreicht. Bei real mode x86 beispielsweise nicht, wenn man es genau nimmt. NB: Diese Plattform illustriert auch, weshalb Vergleich und Arithmetik von Pointern auf verschiedene Arrays unzulässig sind, und zu bizarren Ergebnissen führen können. Soviel zum Brechen von Regeln.
:
Bearbeitet durch User
Ein Funktionszeiger (*f)() ist ein Zeiger auf die erste Instruktion einer Funktion. Was soll (z.B.) (*f)() + 5 sein? Ein Zeiger auf die fünfte Instruktion, oder was?
Markus F. schrieb: > Ein Funktionszeiger (*f)() ist ein Zeiger auf die erste Instruktion > einer Funktion. Auf C-Ebene gibt's kein Konzept von Instruktionen. > Was soll (z.B.) (*f)() + 5 sein? Ein Zeiger auf die fünfte Instruktion, > oder was? Höchstens ein Zeiger auf die fünfte Funktion aus einem Array aus Funktionen. Aber Arrays aus Funktionen gibt es eben nicht, unter anderem da man ja nicht sicherstellen kann, dass alle Funktionen exakt gleich groß sind, was aber Voraussetzung für ein Array ist. Der Nutzen wäre auch eher begrenzt. Da nimmt man dann lieber ein Array aus Funktionszeigern.
c-hater schrieb: > Du hast einfach wirklich keine Ahnung von garnix. Ich biete Dir hiermit an, Deinen Beitrag zu löschen, denn damit hast Du Dich wirklich in besonderer Art und Weise blamiert. So heftig hast Du das bislang noch nicht geschafft. Ich habe auch nichts dagegen, das für die Nachwelt zu erhalten, denn dann können auch andere Forennutzer erkennen, wie sehr von Ahnung und Kenntnis Deine Beiträge nur so triefen. Du kannst auch gerne versuchen, den Fehler wiedergutzumachen und zu erklären, was Du da verbockt hast und wo Dein Fehler liegt. Wie Du mit dem persönlichen Teil umgehst, was Umgangsformen, Beleidigungen etc. angeht, überlasse ich auch in Gänze Dir. Deine Entscheidung.
Mikro 7. schrieb: > In einer gegebenen Implementierung kann einer Funktion f ein Name mit > set(f,name) zugordnet werden. Die funktion get(f) liefert diesen Namen > zurück. Ich wüßte jetzt nicht, wozu man sowas brauchen könnte. Auf Quelltext-Ebene interessiert mich die Funktionsadresse schlichtweg nicht. Ich schreibe immer nur den Namen hin und der Linker kümmert sich dann um die Auflösung.
Rufus Τ. F. schrieb: > c-hater schrieb: >> Du hast einfach wirklich keine Ahnung von garnix. > > Ich biete Dir hiermit an, Deinen Beitrag zu löschen, denn damit hast Du > Dich wirklich in besonderer Art und Weise blamiert. So heftig hast Du > das bislang noch nicht geschafft. Lass das ruhig der Nachwelt erhalten. Die C-Hasser, die überhaupt keinen Schimmer haben, aber unbedingt meinen, mitreden zu müssen, sind mir die liebsten. Ich habe mir auf seinen Beitrag mal ein Lesezeichen gesetzt. Wenn hier im Forum Signaturen üblich wären, hätte ich das direkt mal "gesiggt" :-)
:
Bearbeitet durch Moderator
Mikro 7. schrieb: > Als bizarres Beispiel: > > In einer gegebenen Implementierung kann einer Funktion f ein Name mit > set(f,name) zugordnet werden. Die funktion get(f) liefert diesen Namen > zurück. Das ist wirklich bizarr, der Name ist doch die Adresse, d.h. der Linker übersetzt alle Namen zu Adressen. Zur Laufzeit gibt es also keine Namen mehr im Code. Es ist daher keine Funktion möglich, die den Namen zurück liefert. Man kann bestenfalls ein zusätzliches String-Array anlegen, das Namen enthält. Ob diese dann aber gleich den Funktionsnamen sind, liegt im Ermessen des Programmierers.
Peter D. schrieb: > Es ist daher keine Funktion möglich, die den Namen zurück liefert. Beim Mikrocontroller nicht. Bei Programmen unter den üblichen Betriebssystemen kann das möglich sein, wenn die entsprechende Debug-Info im Image vorhanden 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.