Natrafiłem na fragment kodu void *p = &&abc;. Jakie ma to znaczenie &&? Wiem o odwołaniach do wartości r, ale myślę, że &&w tym kontekście jest inaczej. Co to &&oznacza void *p = &&abc;?
Teraz wyobraź sobie, jak lepsi byliby wszyscy programiści, gdyby gcc miał domyślnie opcję -pedantic. Wtedy ludzie nauczyliby się C zamiast nieistotnych informacji o gnusie.
Lundin
4
Co za włamanie. Jeśli wymyślą nową składnię wskaźników etykiet, powinni również wymyślić dla niej nowy typ zamiast używać void*.
Mark Ransom
1
@Prasoon Saurav: Ktokolwiek przegłosował, prawdopodobnie nie pochwala tej funkcji i wyrzuca ją na ciebie.
Chuck
@Lundin: To samo można powiedzieć o większości kompilatorów. __forceinline? __declspec(naked)? Jednym z moich ulubionych MSVCism jest:, template<typename T> class X { friend T; }który jest nieprawidłowy w C ++ 03.
Sebastian Mach,
Drugie łącze nie działa.
Cœur
96
Jak się tego dowiedzieć
To adres etykiety i jest to funkcja specyficzna dla GCC .
int main(void){void* startp;
s:
startp =&&s;
printf("the assignment above starts at address %p\n", startp);return0;}
Mogłeś się tego dowiedzieć, testując:
int main(void){void* startp;int a;
startp =&&a;
printf("startp=%p\n", startp);return0;}
W takim przypadku GCC mówi:
błąd: etykieta „a” używana, ale nie zdefiniowana
Pod maską - montaż
Musisz znać asemblera, aby naprawdę to zrozumieć, ale spróbuję ci wyjaśnić, co oznacza adres etykiety.
Po załadowaniu przez system operacyjny pliku .exe z dysku, składnik systemu operacyjnego zwany „programem ładującym” (system Windows ma „moduł ładujący PE”, linux ma „moduł ładujący ELF” lub może nawet inne, jeśli są one skompilowane w jądro), dokonuje „wirtualizacji” tego programu, zamieniając go w proces.
Ten proces uważa, że jest jedynym w pamięci RAM i ma dostęp do całej pamięci RAM (to znaczy 0x00000000-0xFFFFFFFF na komputerze 32-bitowym).
(powyższe to tylko krótki przegląd tego, co się dzieje, naprawdę musisz nauczyć się montażu, aby w pełni to zrozumieć, więc bądź ze mną)
Otóż etykieta w kodzie źródłowym jest w zasadzie adresem. „goto label”; nie robi nic poza skokiem do tego adresu (pomyśl o wskaźniku instrukcji w asemblerze). Ta etykieta przechowuje ten adres RAM i w ten sposób możesz znaleźć ten adres.
Po nauczeniu się ASM zdasz sobie sprawę, że ten adres wskazuje na instrukcję w .textsekcji pliku wykonywalnego. .textSekcja jest ten, który posiada (binarnej) kod programu, który ma być wykonany.
Możesz to sprawdzić za pomocą:
objdump -x a.out
Praktyczny przykład
Jak opisano w GCC , możesz użyć tego do zainicjowania tablicy skoków. Niektóre generatory skanerów, takie jak re2c (patrz -gparametr), używają tego do generowania bardziej kompaktowych skanerów. Może jest nawet generator parsera wykorzystujący tę samą technikę.
Odpowiedzi:
&&
to rozszerzenie gcc służące do pobierania adresu etykiety zdefiniowanej w bieżącej funkcji.void *p = &&abc
jest nielegalne w standardowym C99 i C ++.To kompiluje się z g ++.
źródło
void*
.__forceinline
?__declspec(naked)
? Jednym z moich ulubionych MSVCism jest:,template<typename T> class X { friend T; }
który jest nieprawidłowy w C ++ 03.Jak się tego dowiedzieć
To adres etykiety i jest to funkcja specyficzna dla GCC .
Mogłeś się tego dowiedzieć, testując:
W takim przypadku GCC mówi:
Pod maską - montaż
Musisz znać asemblera, aby naprawdę to zrozumieć, ale spróbuję ci wyjaśnić, co oznacza adres etykiety.
Po załadowaniu przez system operacyjny pliku .exe z dysku, składnik systemu operacyjnego zwany „programem ładującym” (system Windows ma „moduł ładujący PE”, linux ma „moduł ładujący ELF” lub może nawet inne, jeśli są one skompilowane w jądro), dokonuje „wirtualizacji” tego programu, zamieniając go w proces.
Ten proces uważa, że jest jedynym w pamięci RAM i ma dostęp do całej pamięci RAM (to znaczy 0x00000000-0xFFFFFFFF na komputerze 32-bitowym).
(powyższe to tylko krótki przegląd tego, co się dzieje, naprawdę musisz nauczyć się montażu, aby w pełni to zrozumieć, więc bądź ze mną)
Otóż etykieta w kodzie źródłowym jest w zasadzie adresem. „goto label”; nie robi nic poza skokiem do tego adresu (pomyśl o wskaźniku instrukcji w asemblerze). Ta etykieta przechowuje ten adres RAM i w ten sposób możesz znaleźć ten adres.
Po nauczeniu się ASM zdasz sobie sprawę, że ten adres wskazuje na instrukcję w
.text
sekcji pliku wykonywalnego..text
Sekcja jest ten, który posiada (binarnej) kod programu, który ma być wykonany.Możesz to sprawdzić za pomocą:
Praktyczny przykład
Jak opisano w GCC , możesz użyć tego do zainicjowania tablicy skoków. Niektóre generatory skanerów, takie jak re2c (patrz
-g
parametr), używają tego do generowania bardziej kompaktowych skanerów. Może jest nawet generator parsera wykorzystujący tę samą technikę.źródło