Forum: Compiler & IDEs Pointer Arithmetic auf Funktionspointer


von Nils P. (torus)


Lesenswert?

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?

von Thomas (Gast)


Lesenswert?

Warum soll das nicht gehen? Übrigens kennt gcc auch einen unären 
&&-Operator und goto *<ptr auf void>

von Rolf M. (rmagnus)


Lesenswert?

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.

von Thomas (Gast)


Lesenswert?

Klar, aber nichts hindert dich, den Funktionspointer in ein unsigned zu 
casten. Wozu auch immer. Und Vergleichen geht mit allem.

von MaWin O. (Gast)


Lesenswert?

Thomas schrieb:
> aber nichts hindert dich, den Funktionspointer in ein unsigned zu
> casten

Die aliasing rules hindern dich daran.

von PittyJ (Gast)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Die einzig wirklich sinnvolle "Arithmetik", die man mit 
Funktionspointern anstellen kann, ist der Vergleich.

von Bernd K. (prof7bit)


Lesenswert?

Rolf M. schrieb:
> und Arrays aus
> Funktionen gibt es nicht.

Es gibt Arrays aus allem erdenklichen, nur die Phantasie des 
Programmierers setzt dem Grenzen.

von Mikro 7. (mikro77)


Lesenswert?

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.

von Nils P. (torus)


Lesenswert?

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!

von Dumdi D. (dumdidum)


Lesenswert?

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?

von Yalu X. (yalu) (Moderator)


Lesenswert?

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

von Jim M. (turboj)


Lesenswert?

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).

von Rolf M. (rmagnus)


Lesenswert?

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.

von c-hater (Gast)


Lesenswert?

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?

von Volker B. (Firma: L-E-A) (vobs)


Lesenswert?

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

von Rolf M. (rmagnus)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

"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
von Markus F. (mfro)


Lesenswert?

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?

von Rolf M. (rmagnus)


Lesenswert?

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.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

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.

von Peter D. (peda)


Lesenswert?

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.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

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
von Peter D. (peda)


Lesenswert?

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.

von (prx) A. K. (prx)


Lesenswert?

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