Ich bin auf einen Code gestoßen void *p = &&abc;. Welche Bedeutung hat &&hier? Ich kenne rWert-Referenzen, aber ich denke &&, dass die Verwendung in diesem Zusammenhang anders ist. Was bedeutet &&in void *p = &&abc;?
Stellen Sie sich nun vor, wie besser jeder Programmierer wäre, wenn gcc standardmäßig -pedantic hätte. Dann würden die Leute C lernen, anstatt irrelevante Informationen über Gnus.
Lundin
4
Was für ein Hack. Wenn sie eine neue Syntax für Beschriftungszeiger erfinden, sollten sie auch einen neuen Typ dafür erfinden, anstatt ihn zu verwenden void*.
Mark Ransom
1
@Prasoon Saurav: Wer auch immer herabgestimmt hat, missbilligt die Funktion wahrscheinlich und nimmt sie an Ihnen heraus.
Chuck
@Lundin: Gleiches gilt für die meisten Compiler. __forceinline? __declspec(naked)? Einer meiner Lieblings-MSVCisms ist : template<typename T> class X { friend T; }, der ungültige C ++ 03 ist.
Sebastian Mach
Der zweite Link ist tot.
Cœur
96
Wie man es herausfindet
Das ist die Adresse eines Etiketts und eine für GCC spezifische Funktion .
int main(void){void* startp;
s:
startp =&&s;
printf("the assignment above starts at address %p\n", startp);return0;}
Sie hätten es selbst herausfinden können, indem Sie Folgendes getestet haben:
int main(void){void* startp;int a;
startp =&&a;
printf("startp=%p\n", startp);return0;}
In diesem Fall sagt GCC:
Fehler: Bezeichnung 'a' verwendet, aber nicht definiert
Unter der Haube - Montage
Sie müssen Assembler kennen, um dies wirklich zu verstehen, aber ich werde versuchen, Ihnen zu erklären, was eine Adresse eines Etiketts bedeutet.
Nachdem das Betriebssystem die EXE-Datei von der Festplatte geladen hat, eine Komponente des Betriebssystems namens "The Loader" (Windows hat den "PE Loader", Linux hat "ELF Loader" oder vielleicht sogar andere, wenn sie in der kompiliert sind Kernel), es macht eine "Virtualisierung" dieses Programms und verwandelt es in einen Prozess.
Dieser Prozess glaubt, dass es der einzige im RAM ist und Zugriff auf den gesamten RAM hat (dh 0x00000000-0xFFFFFFFF auf einem 32-Bit-Computer).
(Das Obige ist nur ein kurzer Überblick über das, was passiert. Sie müssen wirklich die Montage lernen, um es vollständig zu verstehen.
Das Label in einem Quellcode ist im Grunde eine Adresse. "gehe zu Etikett;" macht nichts anderes als einen Sprung zu dieser Adresse (denken Sie an den Befehlszeiger in der Assembly). Dieses Etikett speichert diese RAM-Adresse, und so können Sie diese Adresse herausfinden.
Nachdem Sie ASM gelernt haben, werden Sie feststellen, dass diese Adresse auf eine Anweisung im .textAbschnitt der ausführbaren Datei verweist . Der .textAbschnitt enthält den (Binär-) Code Ihres Programms, der ausgeführt werden soll.
Sie können dies überprüfen mit:
objdump -x a.out
Ein praktisches Beispiel
Wie in GCC beschrieben , können Sie damit eine Sprungtabelle initialisieren. Einige Scannergeneratoren wie re2c (siehe -gParameter) verwenden dies, um kompaktere Scanner zu generieren. Vielleicht gibt es sogar einen Parser-Generator, der dieselbe Technik verwendet.
Antworten:
&&
ist die Erweiterung von gcc , um die Adresse des in der aktuellen Funktion definierten Labels abzurufen.void *p = &&abc
ist in Standard C99 und C ++ illegal.Dies wird mit g ++ kompiliert.
quelle
void*
.__forceinline
?__declspec(naked)
? Einer meiner Lieblings-MSVCisms ist :template<typename T> class X { friend T; }
, der ungültige C ++ 03 ist.Wie man es herausfindet
Das ist die Adresse eines Etiketts und eine für GCC spezifische Funktion .
Sie hätten es selbst herausfinden können, indem Sie Folgendes getestet haben:
In diesem Fall sagt GCC:
Unter der Haube - Montage
Sie müssen Assembler kennen, um dies wirklich zu verstehen, aber ich werde versuchen, Ihnen zu erklären, was eine Adresse eines Etiketts bedeutet.
Nachdem das Betriebssystem die EXE-Datei von der Festplatte geladen hat, eine Komponente des Betriebssystems namens "The Loader" (Windows hat den "PE Loader", Linux hat "ELF Loader" oder vielleicht sogar andere, wenn sie in der kompiliert sind Kernel), es macht eine "Virtualisierung" dieses Programms und verwandelt es in einen Prozess.
Dieser Prozess glaubt, dass es der einzige im RAM ist und Zugriff auf den gesamten RAM hat (dh 0x00000000-0xFFFFFFFF auf einem 32-Bit-Computer).
(Das Obige ist nur ein kurzer Überblick über das, was passiert. Sie müssen wirklich die Montage lernen, um es vollständig zu verstehen.
Das Label in einem Quellcode ist im Grunde eine Adresse. "gehe zu Etikett;" macht nichts anderes als einen Sprung zu dieser Adresse (denken Sie an den Befehlszeiger in der Assembly). Dieses Etikett speichert diese RAM-Adresse, und so können Sie diese Adresse herausfinden.
Nachdem Sie ASM gelernt haben, werden Sie feststellen, dass diese Adresse auf eine Anweisung im
.text
Abschnitt der ausführbaren Datei verweist . Der.text
Abschnitt enthält den (Binär-) Code Ihres Programms, der ausgeführt werden soll.Sie können dies überprüfen mit:
Ein praktisches Beispiel
Wie in GCC beschrieben , können Sie damit eine Sprungtabelle initialisieren. Einige Scannergeneratoren wie re2c (siehe
-g
Parameter) verwenden dies, um kompaktere Scanner zu generieren. Vielleicht gibt es sogar einen Parser-Generator, der dieselbe Technik verwendet.quelle