Saya menemukan sepotong kode void *p = &&abc;
. Apa pentingnya di &&
sini? Saya tahu tentang referensi rvalue tetapi menurut saya yang &&
digunakan dalam konteks ini berbeda. Apa yang &&
menunjukkan dalam void *p = &&abc;
?
Saya menemukan sepotong kode void *p = &&abc;
. Apa pentingnya di &&
sini? Saya tahu tentang referensi rvalue tetapi menurut saya yang &&
digunakan dalam konteks ini berbeda. Apa yang &&
menunjukkan dalam void *p = &&abc;
?
Jawaban:
&&
adalah ekstensi gcc untuk mendapatkan alamat label yang ditentukan dalam fungsi saat ini.
void *p = &&abc
ilegal dalam standar C99 dan C ++.
Ini dikompilasi dengan g ++.
void*
.
__forceinline
? __declspec(naked)
? Salah satu MSVCisms favorit saya adalah:, template<typename T> class X { friend T; }
yang merupakan C ++ 03 yang tidak valid.
Itulah alamat label dan merupakan fitur khusus GCC .
int main(void) {
void* startp;
s:
startp = &&s;
printf("the assignment above starts at address %p\n", startp);
return 0;
}
Anda bisa mengetahuinya sendiri dengan menguji:
int main(void) {
void* startp;
int a;
startp = &&a;
printf("startp=%p\n", startp);
return 0;
}
Dalam hal ini GCC mengatakan:
kesalahan: label 'a' digunakan tetapi tidak ditentukan
Anda perlu mengetahui assembler untuk benar-benar memahami ini, tetapi saya akan mencoba menjelaskan kepada Anda apa arti alamat sebuah label.
Setelah OS memuat file .exe dari disk, komponen sistem operasi disebut "the loader" (windows memiliki "PE Loader", linux memiliki "ELF loader" atau bahkan yang lain, jika dikompilasi di kernel), ia melakukan "virtualisasi" dari program itu, mengubahnya menjadi sebuah proses.
Proses ini menganggapnya sebagai satu-satunya di RAM dan memiliki akses ke seluruh RAM (yaitu, 0x00000000-0xFFFFFFFF pada mesin 32-bit).
(di atas hanyalah ringkasan singkat tentang apa yang terjadi, Anda benar-benar perlu belajar berkumpul untuk memahaminya sepenuhnya, jadi bersabarlah)
Sekarang, label dalam kode sumber pada dasarnya adalah sebuah alamat. "goto label;" tidak melakukan apa pun selain melompat ke alamat itu (pikirkan tentang penunjuk instruksi di assembly). Label ini menyimpan alamat RAM ini, dan begitulah cara Anda mengetahui alamat itu.
Setelah Anda mempelajari ASM, Anda akan menyadari bahwa alamat tersebut menunjuk ke sebuah instruksi di dalam .text
bagian yang dapat dieksekusi. The .text
Bagian adalah salah satu yang memegang program yang ini (biner) kode yang akan dieksekusi.
Anda dapat memeriksanya dengan:
objdump -x a.out
Seperti yang dijelaskan di GCC , Anda dapat menggunakan ini untuk menginisialisasi tabel lompat. Beberapa generator pemindai seperti re2c (lihat -g
parameter) menggunakannya untuk menghasilkan pemindai yang lebih ringkas. Mungkin bahkan ada generator parser yang menggunakan teknik yang sama.