Forum: PC-Programmierung CallbackFunktion übergabe mit oder ohne &


von Marcel (Gast)


Lesenswert?

Hallo,
ich habe einen Funktionsaufruf, wo ich eine andere Funktion als Callback 
mitgeben.
1
void callfunction(data, length, &callbackfunction)
PCLint gibt eine Warnung 546: Suspicious use of &

die genaue erläuterung ist
  Suspicious use of &  -- An attempt was made to take the address
      of a function name. Since names of functions by themselves are
      promoted to address, the use of the & is redundant and could be
      erroneous.

Also hiernach muss eigentlich kein & zeichen davor. Es funktioniert ja 
auch ohne. Warum macht mann es trotzdem?
Evtl. um es einfacher zu erkennen, dass eine Adresse übergeben wird?

Oder hat es noch andere gründe?

Marcel

von DPA (Gast)


Lesenswert?

Ich habe das früher auch mal gemacht, der Konsistenz wegen:

Funktion: ret name(args)
Funktionspointer: ret (*name)(args)

Funktionsaufruf: name()
Funktionspointer aufrufen: (*name)()
Funktionspointer von Funktion: &name

Für jede Dereferenzierung eine Referenzierung und umgekehrt. Nun muss 
man die Referenzierung der Funktion bei der Zuweisung usw. und die 
Dereferenzierung des Funktionspointers beim Aufruf natürlich nicht 
explizit hinschreiben. Für mich hat das mit einfach mehr sinn ergeben. 
Andere lassen beide weg, weil es übersichtlicher sei. Mittlerweile ist 
es mir ziemlich egal geworden. Einfach aufpassen, dass du nicht 
versehentlich Funktionspointer referenzierst, das wäre dann nämlich 
wirklich was anderes.

von x^y (Gast)


Lesenswert?

Ich glaube da liegt wo anders ein Problem. Bitte poste mal die 
Deklaration von "callbackfunction".

von Wilhelm M. (wimalopaan)


Lesenswert?

Marcel schrieb:
> Hallo,
> ich habe einen Funktionsaufruf, wo ich eine andere Funktion als Callback
> mitgeben.
>
1
> void callfunction(data, length, &callbackfunction)

Was meinst Du denn, was Du mit dieser Zeile machst?

von Marcel (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Was meinst Du denn, was Du mit dieser Zeile machst?

Ahso, natürlich ohne das void davor.

Ansonsten rufe ich die callfunktion, welche data und length verarbeitet. 
Wenn diese fertig ist, wird die callbackfunktion aufgerufen.

Beitrag #5849899 wurde vom Autor gelöscht.
von Wilhelm M. (wimalopaan)


Lesenswert?

Marcel schrieb:
> Wilhelm M. schrieb:
>> Was meinst Du denn, was Du mit dieser Zeile machst?
>
> Ahso, natürlich ohne das void davor.
>
> Ansonsten rufe ich die callfunktion, welche data und length verarbeitet.
> Wenn diese fertig ist, wird die callbackfunktion aufgerufen.

Ja. Unter der Annahme, dass das "void" dort nicht steht, hast Du Recht.

Dann wendest Du den Adressoperator auf einen function-designator an. Das 
ist zwar legal, ist aber oft eben nicht gemeint und nicht notwendig. 
Denn Funktionsbezeichner "zerfallen" wie auch Array-Bezeichner zu 
Zeigertypen.

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> Dann wendest Du den Adressoperator auf einen function-designator an. Das
> ist zwar legal, ist aber oft eben nicht gemeint

Wieso? Er will die Adresse der Funktion übergeben. & ist der 
Adress-Operator. Scheint mir exakt das zu sein, was gemeint ist.

> und nicht notwendig.

Das stimmt. Man kann beliebig viele & oder * vor den Namen einer 
Funktion schreiben. Es wird immer ein Zeiger auf die Funktion daraus.

> Denn Funktionsbezeichner "zerfallen" wie auch Array-Bezeichner zu
> Zeigertypen.

Es ist nicht ganz das gleiche wie bei Arrays. Er könnte (durchaus 
überraschenderweise) statt &callbackfunction genauso gut 
*callbackfunction schreiben, und es würde trotzdem das selbe dabei 
rauskommen.

: Bearbeitet durch User
von Marcel (Gast)


Lesenswert?

Also,
ich habe die funktion
1
static void callbacfunction(bool issuccessfull, uint32_t value)
1
static void callfunction(uint32_t data, uint8_t length, void(*callback)(bool issuccessfull, uint32_t value))

Im code rufe ich dann die Funktion
1
callfunction(data, length, callbackfunction)

hier war jetzt meine Frage mit dem &-operator vor callbackfunktion. Also 
wenn ich das jetzt richtig verstanden habe, macht man es nur noch wegen 
der übersichtlichkeit (also dass die Adresse gemeint ist). Ob es jetzt 
davor ist oder nicht, spielt (bei einer Funktion) keine Rolle

von g457 (Gast)


Lesenswert?

> Also wenn ich das jetzt richtig verstanden habe, macht man es nur noch
> wegen der übersichtlichkeit (also dass die Adresse gemeint ist).

Tut man eigentlich nicht, weil der Funktionsname ist ja schon der 
Funktionspointer. Wenn Du Ihn hinmachst, dann wäre das eigentliche 
Ergebnis "Adresse vom Funktionspointer" (nicht "Adresse der Funktion"). 
Deswegen meckern pclint&co korrekterweise, und macht man ihn NICHT hin.

> Ob es jetzt davor ist oder nicht, spielt (bei einer Funktion) keine Rolle

Ja. Außer dass das Hinmachen unnötig für Verwirrung sorgt.

von Wilhelm M. (wimalopaan)


Lesenswert?

g457 schrieb:
>> Also wenn ich das jetzt richtig verstanden habe, macht man es nur noch
>> wegen der übersichtlichkeit (also dass die Adresse gemeint ist).
>
> Tut man eigentlich nicht, weil der Funktionsname ist ja schon der
> Funktionspointer.

Nein.
Ein Funktionsbezeichner und ein Funktionszeiger sind zwei 
unterschiedliche Dinge.

von Rolf M. (rmagnus)


Lesenswert?

Richtig, das & ist nicht nötig, schadet aber auch nicht. Warum dein Lint 
das anmeckert, verstehe ich nicht. Ich hätte da eher erwartet, dass es 
sich beschwert, wenn kein & da steht.

In C++ wäre das bei Zeigern auf nicht-statische Memberfunktionen 
übrigens anders: Dort wäre das & zwingend nötig.

von Wilhelm M. (wimalopaan)


Lesenswert?

Rolf M. schrieb:
> Richtig, das & ist nicht nötig, schadet aber auch nicht. Warum dein Lint
> das anmeckert, verstehe ich nicht.

Die Begründung steht ja da.
Weil es üblich ist (und das Lint das auch so sieht), sich bei 
Funktionsbezeichnern ebenso wie bei Arraybezeichnern auf das Zerfallen 
zu Zeigertypen zu stützen.

von Rolf M. (rmagnus)


Lesenswert?

Wilhelm M. schrieb:
> Rolf M. schrieb:
>> Richtig, das & ist nicht nötig, schadet aber auch nicht. Warum dein Lint
>> das anmeckert, verstehe ich nicht.
>
> Die Begründung steht ja da.
> Weil es üblich ist (und das Lint das auch so sieht), sich bei
> Funktionsbezeichnern ebenso wie bei Arraybezeichnern auf das Zerfallen
> zu Zeigertypen zu stützen.

Bei Arrays gibt es aber auch einen Unterschied zwischen array und 
&array, bei Funktionen nicht. Deshalb sehe ich zumindest mal keinen 
Grund, zu warnen, wenn man das & hinschreibt. Ich sehe auch nirgends 
eine Gefahr, dass man damit das falsche meinen könnte. Und dass es wenig 
gebräuchlich ist, reicht für mich als Begründung für eine Warnung eines 
lint-Tools nicht aus.

Beitrag #5850014 wurde vom Autor gelöscht.
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Rolf M. schrieb:
> Wieso? Er will die Adresse der Funktion übergeben. & ist der
> Adress-Operator. Scheint mir exakt das zu sein, was gemeint ist.

Anders als bei Pointern auf normale Datentypen aber erfolgt das 
Dereferenzieren eines Funktionspointers nicht mit dem *-Operator, 
sondern durch Angeben von runden Klammern (und gegebenenfalls einer 
Parameterliste).

Da verhalten sich der Aufruf einer Funktion über einen Funktionspointer 
und der direkte Aufruf einer Funktion absolut identisch.

Man könnte also auch extrapolieren, daß jeder Funktionsname automatisch 
ein Funktionspointer ist. Und dann ist der Gebrauch des Adressoperators 
in der Tat überflüssig.

von Wilhelm M. (wimalopaan)


Lesenswert?

Rufus Τ. F. schrieb:
> Rolf M. schrieb:
>> Wieso? Er will die Adresse der Funktion übergeben. & ist der
>> Adress-Operator. Scheint mir exakt das zu sein, was gemeint ist.
>
> Anders als bei Pointern auf normale Datentypen aber erfolgt das
> Dereferenzieren eines Funktionspointers nicht mit dem *-Operator,
> sondern durch Angeben von runden Klammern (und gegebenenfalls einer
> Parameterliste).

Wer mag, kann sich ja an folgendem Beispiel erfreuen:
1
void f() {
2
    std::cout << __PRETTY_FUNCTION__ << std::endl;
3
}
4
int main() {
5
    int array[10] {42};
6
    
7
//    decltype(f)::_;
8
//    decltype(&f)::_;
9
10
//    decltype(array)::_;
11
//    decltype(&array)::_;
12
    
13
    auto f1 = f;
14
    f1();
15
    auto f2 = &f;
16
    f2();
17
18
    auto a1 = array;
19
    std::cout << a1[0] << '\n';
20
    auto a2 = &array;
21
    std::cout << a2 << '\n';
22
    std::cout << a2[0] << '\n';
23
}

(werden die auskommentierten Zeilen verwendet, so wird der Typ als 
Fehlermeldung ausgegeben).

von DPA (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> Man könnte also auch extrapolieren, daß jeder Funktionsname automatisch
> ein Funktionspointer ist. Und dann ist der Gebrauch des Adressoperators
> in der Tat überflüssig.

Das ist aber falsch, weil:
1
void funktion(void){} // Funktion
2
void (*funktionspointer)(void) = &funktion;
3
void (**pointer_auf_funktionspointer)(void) = &funktionspointer;

pointer_auf_funktionspointer muss man dereferenzieren um ihn aufrufen zu 
können, und pointer_auf_funktionspointer=&funktion wäre nicht richtig. 
Vermutlich gibt es auch beim Linking bei globalen Symbolen unterschiede. 
Ein Funktionsname und ein Funktionspointer sind also immer noch 
fundamental verschieden, auch wenn man in dem einen Ausnahmefall die 
Referenzierung/Dereferenzierung nicht explizit schreiben muss.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

DPA schrieb:
> pointer_auf_funktionspointer muss man dereferenzieren

Das ist logisch, aber etwas komplett anderes.

von DPA (Gast)


Lesenswert?

Rufus Τ. F. schrieb:
> DPA schrieb:
>> pointer_auf_funktionspointer muss man dereferenzieren
>
> Das ist logisch, aber etwas komplett anderes.

Ganz und garnicht. Dass das Referenzieren eines Funktionsnamen und eines 
Funktionspointers zu anderen Resultaten führt, zeigt, dass man einen 
Funktionsnamen eben nicht als Funktionspointers betrachten kann und 
diese somit etwas komplett anderes sind.

von x^y (Gast)


Lesenswert?

Marcel schrieb:
> Also,

Typo oder Problem: callbacfunction vs callbackfunction? Wird das 
Programm fehlerfrei gelinkt?
1
static void callbacfunction(bool issuccessfull, uint32_t value)
2
3
callfunction(data, length, callbackfunction)

Evtl. verschluckt sich Lint auch nur an der Notation. Passiert das 
gleiche wenn du den Callback Typ separat per typedef definierst, und das 
Argument von callfunction dann über diesen Typ definierst? Z.B. auch 
"typedef struct {...} xyz" würde von Lint bemeckert.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

DPA schrieb:
> Dass das Referenzieren eines Funktionsnamen und eines Funktionspointers
> zu anderen Resultaten führt, zeigt, dass man einen Funktionsnamen eben
> nicht als Funktionspointers betrachten kann und diese somit etwas
> komplett anderes sind.

Das macht Dein Beispiel aber nicht.
1
void funktion(void){} // Funktion
2
void (*funktionspointer)(void) = &funktion;
3
void (**pointer_auf_funktionspointer)(void) = &funktionspointer;

Die zweite Zeile kannst Du nämlich auch so schreiben:
1
void (*funktionspointer)(void) = funktion;

Das macht exakt dasselbe, und das ist der Punkt, um den es geht.

Und wenn Du einen Funktionspointer einem anderen Funktionspointer 
zuweisen willst, sieht das keinen Deut anders aus:
1
void (*anderer_funktionspointer)(void) = funktionspointer;

Der Aufruf der Funktion erfolgt folgendermaßen:
1
funktion();
2
funktionspointer();
3
anderer_funktionspointer();
4
5
*pointer_auf_funktionspointer();

Daß, wenn Du eine zusätzliche Indirektionsebene einführst, diese 
anders gehandhabt werden muss, sollte sich von selbst erschließen.

von Rolf M. (rmagnus)


Lesenswert?

Rufus Τ. F. schrieb:
> Anders als bei Pointern auf normale Datentypen aber erfolgt das
> Dereferenzieren eines Funktionspointers nicht mit dem *-Operator,
> sondern durch Angeben von runden Klammern (und gegebenenfalls einer
> Parameterliste).

Der Dereferenzierungsoperator funktioniert auch auf Funktionspointer. Es 
ist wie beim Adress-Operator: Man kann beide so benutzen, wie man es von 
anderen Typen gewöhnt ist. Optional kann man sie aber auch weglassen.

> Da verhalten sich der Aufruf einer Funktion über einen Funktionspointer
> und der direkte Aufruf einer Funktion absolut identisch.
>
> Man könnte also auch extrapolieren, daß jeder Funktionsname automatisch
> ein Funktionspointer ist. Und dann ist der Gebrauch des Adressoperators
> in der Tat überflüssig.

Wenn das alles wäre, wäre das nicht überflüssig, sondern würde zu einem 
Fehler führen. Denn der &-Operator müsste ja dann die Adresse dieses 
Zeigers ergeben, es kommt aber der Wert des Zeigers raus.

Wilhelm M. schrieb:
> Wer mag, kann sich ja an folgendem Beispiel erfreuen:

Das ist aber nur in C++ möglich, und es ist etwas getrickst. Du hast die 
Unterschiede in den Typen per auto geschickt versteckt.

von Wilhelm M. (wimalopaan)


Lesenswert?

Rolf M. schrieb:
> Wilhelm M. schrieb:
>> Wer mag, kann sich ja an folgendem Beispiel erfreuen:
>
> Das ist aber nur in C++ möglich,

Im Eingangspost lese ich nichts von "nur" C. Und mit C++ kann man eben 
evtl. decaying einfach sichtbar machen.

> und es ist etwas getrickst.

Mitnichten. Du hast die Möglichkeiten des Beispiels gar nicht erkannt 
oder probiert.

> Du hast die
> Unterschiede in den Typen per auto geschickt versteckt.

Auch das nicht, ganz im Gegenteil (s.o.).
Auf die o.g. Weise gibt es kein evtl. decay der designator zu pointern.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wer in
1
  callfunction(data, length, &callbackfunction)

den Adressoperator vor callbackfunction verwendet, der sollte ihn
konsequenterweise auch bei Funktionsaufrufen verwenden, also bspw. nicht

1
  printf("%f\n", sin(x));

schreiben, sondern

1
  (&printf)("%f\n", (&sin)(x));

denn auch bei einem Funktionsaufruf wird nach ISO vor der öffnenden
Argumentklammer ein Funktionspointer erwartet:

1
The expression that denotes the called function shall have type pointer
2
to function returning void or returning a complete object type other
3
than an array type.

Wer hier die Adressoperatoren vor printf und sin weglässt (also
praktisch jeder vernünftige C-Programmierer), weil die Funktionsnamen
schon implizit in Funktionpointer konvertiert werden, sollte ihn auch im
ersten Beispiel vor callbackfunction weglassen.

Warum PC-Lint bei Verwendung des Adressoperators meint, das "could be
erroneous", verstehe ich aber auch nicht.

: Bearbeitet durch Moderator
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Yalu X. schrieb:
> der sollte ihn
> konsequenterweise auch bei Funktionsaufrufen verwenden

Sehr ... äh, "schön".

von Wilhelm M. (wimalopaan)


Lesenswert?

Yalu X. schrieb:
> Wer in
>
>
1
>   callfunction(data, length, &callbackfunction)
2
>
>
> den Adressoperator vor callbackfunction verwendet, der sollte ihn
> konsequenterweise auch bei Funktionsaufrufen verwenden, also bspw. nicht
>
>
>
1
>   printf("%f\n", sin(x));
2
>
>
> schreiben, sondern
>
>
>
1
>   (&printf)("%f\n", (&sin)(x));
2
>
>
> denn auch bei einem Funktionsaufruf wird nach ISO vor der öffnenden
> Argumentklammer ein Funktionspointer erwartet:

Das lässt sich aber nicht konsequent durchhalten, weil dies
1
int foo(int(*f)(int), int v) {
2
    return (&f)(v);
3
}

natürlich zu einem Fehler führt.

Übrigens natürlich auch bei
1
template<typename F, typename V>
2
int tf(F f, V v) {
3
    return (&f)(v);
4
}

da auch hier die Adresse der Parametervariablen bestimmt wird.

Daher ist die Forderung / das Vorgehen, den Adressoperator zu verwenden, 
Quatsch und Lint hat absolut Recht.

von DPA (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Daher ist die Forderung / das Vorgehen, den Adressoperator zu verwenden,
> Quatsch und Lint hat absolut Recht.

Beim referenzieren eines Funktionsnamen um diesen dann als 
Funktionspoiner zwischenzuspeichern oder an eine Funktion zu übergeben, 
sowie das Dereferenzieren von Funktionspointern vor dem Aufruf  sind 
stylistische Entscheidung. Es gibt da kein Richtig oder Falsch und kein 
Recht oder Unrecht in dem Fall.

Wilhelm M. schrieb:
> Yalu X. schrieb:
>> denn auch bei einem Funktionsaufruf wird nach ISO vor der öffnenden
>> Argumentklammer ein Funktionspointer erwartet:
>
> Das lässt sich aber nicht konsequent durchhalten, weil dies
> int foo(int(*f)(int), int v) {
>     return (&f)(v);

Während Yalu hier sehr gut die Absurdität dieser Diskussion im Bezug auf 
die Streiterei um die Schreibweise aufgrund der strikten Semantik willen 
deutlich macht, scheint mir, dass du sein Argument, weshalb (&sin)(x) 
statt sin(x) geschrieben werden müsste, missverstanden hast.

sin ist ein Funktionsname, der () operator erwartet einen 
Funktionspointer in C, Im falle int(*f)(int) ist f bereits ein 
Funktionspointer, aber sin nicht, deshalb wäre das einzig strikt 
Konsistente, f() direckt aufzurufen, aber (&sin)() vorher zu 
referenzieren.

Dies unterscheidet sich übrigens von meinem ursprünglichen Argument, wo 
ich argumentiere, dass man Funktionsnamen bei der Umwandlung nach 
Funktionspointern explizit referenzieren, und bei Benutzung als 
Funktionsname explizit dereferenzieren sollte (insbesondere auch wenn 
man Funktionsnamen immer direkt mit () aufruft), um Funktionsnamen und 
Funktionspointer zu Unterscheiden und Konsistenz im Bezug auf anzahl 
Referenzierungen mit & und Dereferenzierungen mit * zu wahren. Beide 
Argumente basieren aber auf strikter Einhaltung semantischer 
Konsistentz.

von Torsten R. (Firma: Torrox.de) (torstenrobitzki)


Lesenswert?

Rolf M. schrieb:
> Richtig, das & ist nicht nötig, schadet aber auch nicht. Warum dein Lint
> das anmeckert, verstehe ich nicht. Ich hätte da eher erwartet, dass es
> sich beschwert, wenn kein & da steht.

Hätte ich auch so etwartet, wie Du. Tools wie Lint werden übrigens auch 
nur von Menschen geschrieben, die eben auch Ihre Vorlieben und Meinungen 
haben. Und Lint kann man entsprechend seien eigenen Vorlieben und 
Meinungen konfigurieren ;-)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
> Yalu X. schrieb:
>> ...
>> denn auch bei einem Funktionsaufruf wird nach ISO vor der öffnenden
>> Argumentklammer ein Funktionspointer erwartet:
>
> Das lässt sich aber nicht konsequent durchhalten

Doch, muss sogar, sonst meckert der Compiler.

> weil dies
>
> int foo(int(*f)(int), int v) {
>     return (&f)(v);
> }
>
> natürlich zu einem Fehler führt.

Logisch, weil vor der Argumentklammer kein Funktionspointer, sondern ein
Pointer auf einen solchen steht.

> Übrigens natürlich auch bei
>
> template<typename F, typename V>
> int tf(F f, V v) {
>     return (&f)(v);
> }
>
> da auch hier die Adresse der Parametervariablen bestimmt wird.
>
> Daher ist die Forderung / das Vorgehen, den Adressoperator zu verwenden,
> Quatsch und Lint hat absolut Recht.

Kann man so sehen.

Ich frage mich allerdings, warum es in C (und C++) überhaupt einen
eigenen Typ für Funktionen (nicht Funtionspointer) gibt. Anders als der
Typ für Arrays hat er so gut wie keinen Nutzen.

Beim Array kann man den Typ dazu benutzen, einen Pointer auf das gesamte
Array (und nicht nur auf das erste Element) zu definieren. Außerdem kann
man darauf sizeof anwenden, um die Größe des Arrays zu erhalten. In
allen Ausdrücken, in denen dem Array-Vezeichner kein & oder sizeof
vorangeht, wird er in einen Pointer auf das erste Element konvertiert.

Aber wie ist es bei Funktionen?

Der Adressoperator vor einem Funktionsbezeichner liefert genau den
gleichen Pointer wie die implizite Konvertierung, ist also redundant.
Ein sizeof vor einem Funktionsbezeichner ist ein Fehler. In allen
anderen Fällen wird der Funktionsbezeichner in einen Funktionspointer
konvertiert.

Die einzige halbwegs sinnvolle Verwendung eines Funktionstyps ist IMHO
in einem Typedef. Beispiel:

1
// R2toR: function of type R²->R
2
3
typedef double R2toR(double, double);
4
5
// f1: R²->R
6
R2toR f1;
7
8
// f2, f3: R²->R
9
R2toR f2, f3;

Ohne diesen Typedef müsste man schreiben:

1
double f1(double, double);
2
double f2(double, double), f3(double, double);

Man spart sich also bei vielen gleichartigen Funktionsdeklarationen
etwas Schreibarbeit und gewinnt etwas an Übersichtlichkeit. In freier
Wildbahn habe ich diese Vorgehensweise allerdings auch noch nicht
gesehen, das scheint also ein ungenutztes Feature von C zu sein.

Deswegen wäre es IMHO sinnvoller gewesen, in der Sprachespezifikation
von C den Typ für Funktionen gar nicht erst einzuführen und stattdessen
einem Funktionsbezeichner von vornherein den Typ eines Funktionspointers
zu geben, so dass er nicht erst implizit oder explizit in einen solchen
konvertiert werden muss. Die Dereferenzierung eines Funktionspointers
wäre demzufolge ein Fehler, da für wäre sizeof erlaubt und würde die
Größe eine Code-Adresse liefern.

von Wilhelm M. (wimalopaan)


Lesenswert?

DPA schrieb:

> Während Yalu hier sehr gut die Absurdität dieser Diskussion im Bezug auf
> die Streiterei um die Schreibweise aufgrund der strikten Semantik willen
> deutlich macht, scheint mir, dass du sein Argument, weshalb (&sin)(x)
> statt sin(x) geschrieben werden müsste, missverstanden hast.

Denke ich nicht.

>
> sin ist ein Funktionsname,

Das mag so sein, muss aber nicht. Es kann auch eine Zeigervariable ein, 
dass kann man an seinem Beispiel nicht sehen.

von DPA (Gast)


Lesenswert?

Wilhelm M. schrieb:
>>
>> sin ist ein Funktionsname,
>
> Das mag so sein, muss aber nicht. Es kann auch eine Zeigervariable ein,
> dass kann man an seinem Beispiel nicht sehen.

[sarkasmus]
Ja, daran das dass dann aber nicht mehr funktionieren würde ist 
natürlich nicht klar, dass das nicht so ist, klar. Das hier absichtlich 
Standardlibraryfunktionen genommen wurden, welche auch kein 
Zeigervariablen sein dürfen sondern Funktionsnamen sein müssen, ändert 
daran natürlich auch nichts. Jaja, dass muss nicht nur für 
Funktionsnamen gemeint gewesen sein, das wäre ja zu offensichtlich, 
klar.
[/sarkasmus]

von Wilhelm M. (wimalopaan)


Lesenswert?

DPA schrieb:
> Wilhelm M. schrieb:
>>>
>>> sin ist ein Funktionsname,
>>
>> Das mag so sein, muss aber nicht. Es kann auch eine Zeigervariable ein,
>> dass kann man an seinem Beispiel nicht sehen.
>
> [sarkasmus]
...
> [/sarkasmus]

Du hast wenig von meinem Post verstanden: Du lässt auch generischen Code 
außer Acht.

: Bearbeitet durch User
von Yalu X. (yalu) (Moderator)


Lesenswert?

Wilhelm M. schrieb:
>>
>> sin ist ein Funktionsname,
>
> Das mag so sein, muss aber nicht. Es kann auch eine Zeigervariable ein,
> dass kann man an seinem Beispiel nicht sehen.

Um diese Unklarheit aufzulösen: Das printf und das sin in meinem
Beispiel sollen tatsächlich Funktionsnamen und keine Zeigervariablen
sein, sonst hätte ich keine Funktionen aus der Standardbibliothek,
sondern irgendwelche Phantasienamen verwendet.

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.