Ich kann das nicht herausfinden:
int main() {
int (*) (int *) = 5;
return 0;
}
Die obige Zuordnung wird mit g ++ c ++ 11 kompiliert. Ich weiß, dass dies int (*) (int *)
ein Zeiger auf eine Funktion ist, die ein (int *)
Argument als akzeptiert und ein int zurückgibt, aber ich verstehe nicht, wie Sie es mit 5 gleichsetzen können. Zuerst dachte ich, es ist eine Funktion, die ständig 5 zurückgibt (aus meinem letzten Lernen in F #, wahrscheinlich, haha), dann dachte ich kurz, dass der Funktionszeiger auf Speicherplatz 5 zeigt, aber das funktioniert eindeutig nicht und Hex-Werte auch nicht.
Da ich dachte, dass dies daran liegen könnte, dass die Funktion ein int zurückgibt und dass das Zuweisen eines int (irgendwie) in Ordnung ist, habe ich auch Folgendes versucht:
int * (*) (int *) = my_ptr
Dabei my_ptr
handelt es sich um int *
den gleichen Typ wie dieser zweite Funktionszeiger, wie im ersten Fall mit dem Typ int. Dies wird nicht kompiliert. Das Zuweisen von 5 oder eines beliebigen int-Werts anstelle von my_ptr
wird auch für diesen Funktionszeiger nicht kompiliert.
Was bedeutet die Aufgabe?
Update 1
Wir haben die Bestätigung, dass es sich um einen Fehler handelt, wie in der besten Antwort gezeigt. Es ist jedoch immer noch nicht bekannt, was tatsächlich mit dem Wert geschieht , den Sie dem Funktionszeiger zuweisen, oder was mit der Zuweisung geschieht. Alle (guten) Erklärungen dazu wären sehr dankbar! Weitere Informationen zum Problem finden Sie in den folgenden Änderungen.
Bearbeiten 1
Ich benutze gcc Version 4.8.2 (in Ubuntu 4.8.2)
Bearbeiten 2
Eigentlich funktioniert es auf meinem Compiler, es mit irgendetwas gleichzusetzen. Sogar das Gleichsetzen mit einer std :: string-Variablen oder einem Funktionsnamen, der ein Double zurückgibt, funktioniert.
Bearbeiten 2.1
Interessanterweise kann es kompiliert werden, wenn es zu einem Funktionszeiger auf eine Funktion gemacht wird, die einen Datentyp zurückgibt, der kein Zeiger ist, z
std::string (*) () = 5.6;
Sobald sich der Funktionszeiger jedoch auf eine Funktion bezieht, die einen Zeiger zurückgibt, wird er nicht kompiliert, z. B. mit
some_data_type ** (*) () = any_value;
quelle
error: expected identifier or '(' before ')' token
int *x = 5
dir hat es benanntx
. Damitint * (*x) (int *) = 5
wird nicht kompiliert. (obwohl das als C-Code kompiliert wird).int(*) = 5;
undint(*);
Antworten:
Es ist ein Fehler in g ++.
ist ein Typname.
In C ++ können Sie keine Deklaration mit einem Typnamen ohne Bezeichner haben.
Das kompiliert also mit g ++.
und dies kompiliert auch:
aber sie sind beide ungültige Erklärungen.
EDIT :
TC erwähnt in den Kommentaren Bugzilla Bug 60680 mit einem ähnlichen Testfall, der
jedoch noch nicht genehmigt wurde. Der Fehler wird in Bugzilla bestätigt.EDIT2 :
Wenn sich die beiden obigen Deklarationen im Dateibereich befinden, gibt g ++ eine Diagnose korrekt aus (die Diagnose wird im Blockbereich nicht ausgegeben).
EDIT3 :
Ich habe das Problem in der neuesten Version von g ++ Version 4 (4.9.2), der neuesten Vorabversion 5 (5.0.1 20150412) und der neuesten experimentellen Version 6 (6.0.0 20150412) überprüft und kann es reproduzieren.
quelle
error C2059: syntax error : ')'
int (*int_func)(int *);
welcher einen Funktionszeiger mit dem Namen deklariertint_func
.int x[5];
und nichtint[5] x;
Es ist nicht gültig C ++. Denken Sie daran, dass Ihr bestimmter Compiler, der gerade kompiliert, nicht gültig ist. Compiler haben, wie jede komplexe Software, manchmal Fehler, und dies scheint einer zu sein.
Im Gegensatz dazu
clang++
beschwert sich:Dies ist das erwartete Verhalten, da die fehlerhafte Zeile in C ++ nicht gültig ist. Es gibt vor, eine Zuweisung zu sein (wegen der
=
), enthält jedoch keine Kennung.quelle
Wie andere Antworten gezeigt haben, ist es ein Fehler, dass
kompiliert. Eine vernünftige Annäherung an diese Aussage, von der erwartet wird, dass sie eine Bedeutung hat, ist:
Jetzt
proc
ist ein Zeiger auf eine Funktion, der erwartet, dass die Adresse5
die Basisadresse einer Funktion ist, die eine nimmtint*
und eine zurückgibtint
.Bei einigen Mikrocontrollern / Mikroprozessoren kann
5
es sich um eine gültige Code-Adresse handeln, und es kann möglich sein, eine solche Funktion dort zu lokalisieren.Auf den meisten Universalcomputern ist die erste Speicherseite (Adressen
0-1023
für 4K-Seiten) absichtlich ungültig (nicht zugeordnet), um sie abzufangennull
.Während das Verhalten von der Plattform abhängt, kann man vernünftigerweise erwarten, dass ein Seitenfehler auftritt, wenn er
*proc
aufgerufen wird (z(*proc)(&v)
. B. ). Vor der Zeit, zu der*proc
aufgerufen wird, geschieht nichts Ungewöhnliches.Wenn Sie keinen dynamischen Linker schreiben, sollten Sie Adressen mit ziemlicher Sicherheit nicht numerisch berechnen und sie Zeiger-Funktions-Variablen zuweisen.
quelle
Diese Befehlszeile generiert viele Zwischendateien. Der erste von ihnen
so.cpp.170r.expand
sagt:Dies beantwortet immer noch nicht genau, was passiert, aber es sollte ein Schritt in die richtige Richtung sein.
quelle