Betrachtet man, was im nginx-Quellcode vor sich geht, ist die Semantik der geelementptr-Anweisung interessant. Es ist das Ergebnis von zwei Zeilen Code C-Quelle:
ev = (ngx_event_t *) ((char *) node - offsetof(ngx_event_t, timer));
ev->handler(ev);
node
ist vom Typ ngx_rbtree_node_t
, die ngx_event_t
Mitglied ev
‚s-Typ ist. Das ist wie:
struct ngx_event_t {
....
struct ngx_rbtree_node_t time;
....
};
struct ngx_event_t *ev;
struct ngx_rbtree_node_t *node;
timer
ist der Name der Struktur ngx_event_t
Mitglied in dem node
zeigen sollte.
|<- ngx_rbtree_node_t ->|
|<- ngx_event_t ->|
------------------------------------------------------
| (some data) | "time" | (some data)
------------------------------------------------------
^ ^
ev node
Die obige Grafik zeigt das Layout einer Instanz ngx_event_t
. Das Ergebnis von offsetof(ngx_event_t, time)
ist 40. Das bedeutet, dass some data
vor time
40 Byte ist. Und die Größe von ngx_rbtree_node_t
ist auch 40 Bytes, durch Zufall. So i64 -1
in der ersten Index oprand des Getementptr Befehl berechnet die Basisadresse des ngx_event_t
enthält node
, die 40 Bytes vor node
ist.
handler
ist ein weiteres Mitglied von ngx_event_t
, die 16 Bytes hinter der Basis von ngx_event_t
ist. Durch eine (weitere) Koinzidenz liegt das dritte Glied von ngx_rbtree_node_t
ebenfalls 16 Bytes hinter der Basisadresse von ngx_rbtree_node_t
. So wird die i32 2
in geteilelementptr Anweisung 16 Bytes zu ev
hinzufügen, um die Adresse handler
zu erhalten.
Beachten Sie, dass die 16 Bytes aus dem Layout ngx_rbtree_node_t
, aber nicht ngx_event_t
berechnet werden. Clang muss einige Berechnungen durchgeführt haben, um die Korrektheit der geteileptr Anweisung sicherzustellen. Bevor der Wert %handler
verwendet wird, gibt es eine Bitcast-Anweisung, die %handler
auf einen Funktionszeigertyp umsetzt.
Was Clang getan hat, bricht den im C-Quellcode definierten Typentransformationsprozess. Aber das Ergebnis ist genau das Gleiche.
Das stimmt. Aber der Zweck, diesen negativen Wert zu verwenden, ist interessant. Ich habe es in einer anderen Antwort erklärt. – xywang