Saya melihat kode sumber untuk nmap yang dirilis pada tahun 1997 dan saya perhatikan bagian kode ini yang terlihat sedikit aneh bagi saya:
int i=0, j=0,start,end;
char *expr = strdup(origexpr);
ports = safe_malloc(65536 * sizeof(short));
i++; /* <<<<<< */
i--; /* <<<<<< */
for(;j < exlen; j++)
if (expr[j] != ' ') expr[i++] = expr[j];
expr[i] = '\0';
Mengapa kamu memiliki i++;
dan kemudian i--;
setelah satu sama lain? i
adalah 0
, lalu i++
beralih i
ke 1
. Setelah itu, i--
beralih i
ke 0
.
Tautan ke kode sumber asli. Pencarian untuk:
i++;
i--;
Adakah yang bisa menjelaskan untuk apa ini?
-O
itu memang mengoptimalkan pernyataan-pernyataan itu.Jawaban:
Ini adalah bug. Garis-garis ini bersama-sama menghasilkan
i
tidak berubah, jadi mereka seharusnya tidak ada di sana.Artikel tertaut yang memperkenalkan nmap diterbitkan pada 1 September 1997. Jika Anda melihat repositori SVN untuk nmap di https://svn.nmap.org/nmap , revisi awal yang diperiksa pada 10 Februari 1998 tidak memiliki baris-baris berikut:
Jadi ini adalah sesuatu yang penulis temukan dan perbaiki antara menerbitkan kode sumber nmap awal dan checkin awal ke SVN.
sumber
<pre>
tag di sekitar artikel; Inspektur Chrome mengungkapkan bagaimana itu mengarah pada beberapa dokumen mangling selama konstruksi DOM;)i
bukan int tetapi beberapa kelas mewah dengan kelebihan operator, itu mungkin (meskipun tidak mungkin dan umumnya merupakan tanda praktik pengkodean yang buruk) bahwa ini dapat memiliki beberapa efek samping. (Hanya berlaku jika ini C ++ tentu saja.)Percuma saja. Sama sekali tidak apa-apa.
Jika saya berspekulasi itu mungkin sisa-sisa kode debugging yang digunakan selama pengembangan.
Saya menduga salah satu
i++
ataui--
diperkenalkan dalam satu perubahan dan yang lain diperkenalkan pada yang lain.Saya tidak memiliki cara untuk menemukan titik pengantar, karena tidak ada riwayat revisi antara rilis sumber awal dan revisi SVN pertama.
sumber
Untuk kompiler yang tidak mengoptimalkan, atau yang mengenali efek samping perangkat keras, i ++; urutan i-- akan menyebabkan saya dibaca dari memori, kemudian ditulis ulang, terlepas dari jalur yang diambil melalui for for dan bersarang jika.
Dalam pemrosesan paralel, kadang-kadang hack kompiler diambil untuk memastikan urutan kode menggunakan salinan variabel lokalnya sendiri daripada salinan global.
Karena contohnya adalah potongan kode, seseorang tidak dapat menentukan kompiler yang digunakan, sistem operasi / perangkat keras yang diharapkan, atau apakah ini dalam urutan kode / fungsi yang mungkin dapat dieksekusi sebagai utas independen.
Dalam sistem yang lebih sederhana, saya sementara telah memaksa perubahan pada variabel untuk menjalankan fitur perangkap di lingkungan debugging. Jika itu yang terjadi, penulis mungkin lupa menghapus kode ketika pengembangan selesai.
sumber
i
sebagai variabel lokal ditunjukkan dalam kode di atas, dan tidak ada cara untuk dapat diakses oleh utas lain pada titik di manai++; i--
garis-garisnya.i
dipaksa menjadi non-volatile. Saya belum pernah berurusan dengan threading di C atau C ++, jadi saya tidak tahu bagaimana itu bisa dianggap volatile dan bagaimanai++; i--
akan menekannya.Saya akan menyarankan Anda untuk memeriksa kode yang diperbarui saja. Jika Anda menggunakan (i = 2 +1) tepat setelah itu (i-1) itu tidak masuk akal. Nilai i tetap tidak berubah. Anda dapat mencobanya menggunakan kompiler c atau c ++. atau bahkan dalam bahasa lain sama saja. Jalankan kode di kompiler untuk melihat apakah saya salah atau benar, dan beri tahu saya jika saya memberikan jawaban yang salah.
sumber