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;?
Sekarang bayangkan bagaimana semua orang akan menjadi programmer yang lebih baik jika gcc memiliki -pedantic secara default. Kemudian orang akan mempelajari C, bukan informasi yang tidak relevan tentang gnus.
Lundin
4
Benar-benar hack. Jika mereka menemukan sintaks baru untuk penunjuk label, mereka harus menemukan tipe baru untuk itu juga daripada menggunakan void*.
Mark Ransom
1
@Prasoon Saurav: Siapa pun yang memberikan suara negatif mungkin tidak menyetujui fitur tersebut dan menimpanya kepada Anda.
Chuck
@ Lundin: Hal yang sama dapat dikatakan pada kebanyakan kompiler. __forceinline? __declspec(naked)? Salah satu MSVCisms favorit saya adalah:, template<typename T> class X { friend T; }yang merupakan C ++ 03 yang tidak valid.
Sebastian Mach
Tautan kedua sudah mati.
Cœur
96
Bagaimana cara menemukannya
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);return0;}
Anda bisa mengetahuinya sendiri dengan menguji:
int main(void){void* startp;int a;
startp =&&a;
printf("startp=%p\n", startp);return0;}
Dalam hal ini GCC mengatakan:
kesalahan: label 'a' digunakan tetapi tidak ditentukan
Di bawah kap - perakitan
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 .textbagian yang dapat dieksekusi. The .textBagian adalah salah satu yang memegang program yang ini (biner) kode yang akan dieksekusi.
Anda dapat memeriksanya dengan:
objdump -x a.out
Contoh praktis
Seperti yang dijelaskan di GCC , Anda dapat menggunakan ini untuk menginisialisasi tabel lompat. Beberapa generator pemindai seperti re2c (lihat -gparameter) menggunakannya untuk menghasilkan pemindai yang lebih ringkas. Mungkin bahkan ada generator parser yang menggunakan teknik yang sama.
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 ++.
sumber
void*
.__forceinline
?__declspec(naked)
? Salah satu MSVCisms favorit saya adalah:,template<typename T> class X { friend T; }
yang merupakan C ++ 03 yang tidak valid.Bagaimana cara menemukannya
Itulah alamat label dan merupakan fitur khusus GCC .
Anda bisa mengetahuinya sendiri dengan menguji:
Dalam hal ini GCC mengatakan:
Di bawah kap - perakitan
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:
Contoh praktis
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.sumber