Ich habe diesen Code auf GitHub gefunden, ihn aber nicht ganz verstanden:
#define lambda(ret_type, _body) ({ ret_type _ _body _; })
Dann:
int (*max)(int, int) = lambda(int,
(int x, int y) {
return x > y ? x : y;
});
int max_value = max(1, 2);
// max_value is 2
Was machen die Unterstriche im #define
und wie gibt es einen Funktionszeiger zurück?
gcc -E
) zu erweitern, um zu sehen, was es tut?Antworten:
Mit diesem Makro
erweitert sich zu:
In geschweiften Klammern werden dabei die verschachtelten Funktionen von GCC verwendet , um eine Funktion zu erstellen, die die gewünschte Operation ausführt. Im inneren Bereich hat es den Namen
_
.Dann werden, wie von interjay festgestellt, die Statement-Ausdrücke von GCC verwendet. Tatsächlich wird die Funktion
_
dem Zeiger zugewiesenmax
.Wenn ein solches Makro nicht verwendet wird, kann dies anders geschrieben und wie folgt verwendet werden:
Die drei Methoden können in diesem Codebeispiel verglichen werden .
quelle
max(4, -30);
stattapply_binary_op(max, 4, -30);
?Dies wird als Anweisungsausdruck bezeichnet und erzeugt ein "Lambda" (oder eine verschachtelte Funktion) ) und gibt einen Zeiger darauf zurück. Es ist GNU C-spezifisch.
Das Makro wird erweitert zu:
Das
_
am Ende ist wie einreturn
.Der Unterstrich ist eigentlich der Name der Funktion, die erstellt und "zurückgegeben" wird. Es wird verwendet, weil es ein selten verwendeter Bezeichner ist (aus gutem Grund;
_
möglicherweise der am wenigsten beschreibende Bezeichner).Der Grund, warum der Anweisungsausdruck verwendet wird,
_
wird nicht definiert, nachdem der Gültigkeitsbereich des Anweisungsausdrucks beendet wurde.Gehen Sie also das Makro durch:
ret_type
ist der Rückgabetyp des "Lambda"._
ist der Name der darin verwendeten Funktion, da es sich um einen ungewöhnlichen Bezeichnernamen handelt._body
besteht aus den Argumenten und dem Hauptteil der Funktion. Das nachfolgende_
"gibt" das "Lambda" zurück.Dieser Code befindet sich unter Let's Destroy C (ein geeigneter Name). Du solltest es nicht benutzen. Ihr Code funktioniert nur auf Compilern, die GNU C-Erweiterungen unterstützen. Schreiben Sie stattdessen einfach eine Funktion oder ein Makro.
Wenn Sie solche Konstrukte häufig verwenden oder mehr Funktionen wünschen, empfehle ich die Verwendung von C ++. Mit C ++ können Sie etwas Ähnliches tun und über tragbaren Code verfügen.
quelle