Dengan anggapan bahwa kompiler C ++ Anda mendukungnya, apakah ada alasan khusus untuk tidak menggunakannya __FILE__
, __LINE__
dan __FUNCTION__
untuk tujuan logging dan debugging?
Saya terutama prihatin dengan memberikan data yang menyesatkan pengguna — misalnya, melaporkan nomor baris yang salah atau fungsi sebagai hasil dari optimasi — atau sebagai akibatnya mendapatkan hasil yang mengejutkan.
Pada dasarnya, dapatkah saya percaya __FILE__
, __LINE__
dan __FUNCTION__
untuk selalu melakukan hal yang benar?
c++
debugging
logging
c-preprocessor
Dapat diakses
sumber
sumber
Jawaban:
__FUNCTION__
tidak standar,__func__
ada di C99 / C ++ 11. Yang lain (__LINE__
dan__FILE__
) baik-baik saja.Itu akan selalu melaporkan file dan baris yang tepat (dan berfungsi jika Anda memilih untuk menggunakan
__FUNCTION__
/__func__
). Optimalisasi adalah non-faktor karena merupakan ekspansi makro waktu kompilasi; itu tidak akan pernah mempengaruhi kinerja dengan cara apa pun.sumber
__func__
adalah jenis masalah di C ++. C99 tidak mengatakan sepatah kata pun tentang argumen default dan sebagainya, kasus di mana tidak begitu jelas bagaimana__func__
seharusnya berperilaku di C ++.__func__
ada di c99, bukan c ++. Terlepas dari itu, saya pikir implementasi yang masuk akal__func__
dalam c + + hanya akan menghasilkan nama hancur. Karena saya bukan penulis kompiler, itu bukan panggilan saya.__FUNCTION__
sama sekali? Kompiler apa kecuali gcc baru-baru ini memperlakukan ini sebagai variabel, bukan makro?__func__
sekarang dalam standar C ++ 11.Dalam kasus yang jarang terjadi, akan berguna untuk mengubah garis yang diberikan oleh
__LINE__
kepada hal lain. Saya telah melihat konfigurasi GNU melakukan itu untuk beberapa tes untuk melaporkan nomor baris yang sesuai setelah itu memasukkan beberapa voodoo antara baris yang tidak muncul dalam file sumber asli. Sebagai contoh:Akan membuat baris berikut dimulai dengan
__LINE__
100. Anda dapat menambahkan nama file baru secara opsionalIni jarang berguna. Tetapi jika dibutuhkan, tidak ada alternatif yang saya tahu. Sebenarnya, alih-alih baris, makro dapat digunakan juga yang harus menghasilkan salah satu dari dua bentuk di atas. Menggunakan perpustakaan preprocessor boost, Anda dapat menambah baris saat ini dengan 50:
Saya pikir sangat berguna untuk menyebutkannya karena Anda bertanya tentang penggunaan
__LINE__
dan__FILE__
. Satu tidak pernah mendapat cukup kejutan dari C ++ :)Sunting: @Jonathan Leffler memberikan beberapa kasus penggunaan yang lebih baik dalam komentar:
sumber
FYI: g ++ menawarkan makro __PRETTY_FUNCTION__ non-standar. Sampai sekarang saya tidak tahu tentang C99 __func__ (terima kasih Evan!). Saya pikir saya masih lebih suka __PRETTY_FUNCTION__ bila tersedia untuk pelingkupan kelas tambahan.
PS:
sumber
Secara pribadi, saya enggan menggunakan ini untuk apa pun selain pesan debugging. Saya telah melakukannya, tetapi saya berusaha untuk tidak menunjukkan informasi seperti itu kepada pelanggan atau pengguna akhir. Pelanggan saya bukan insinyur dan terkadang tidak paham komputer. Saya mungkin mencatat info ini ke konsol, tetapi, seperti yang saya katakan, dengan enggan kecuali untuk debug builds atau untuk alat internal. Saya kira itu tergantung pada basis pelanggan yang Anda miliki.
sumber
C ++ 20
std::source_location
C ++ akhirnya menambahkan opsi non-makro, dan itu kemungkinan akan mendominasi di beberapa titik di masa mendatang ketika C ++ 20 menyebar luas:
Dokumentasi mengatakan:
di mana NTBS berarti "Null Terminated Byte String".
Saya akan mencobanya ketika dukungan datang ke GCC, GCC 9.1.0 dengan
g++-9 -std=c++2a
masih tidak mendukungnya.https://en.cppreference.com/w/cpp/utility/source_location klaim penggunaan akan seperti:
Output yang mungkin:
__PRETTY_FUNCTION__
vs__FUNCTION__
vs__func__
vsstd::source_location::function_name
Dijawab di: Apa perbedaan antara __PRETTY_FUNCTION__, __FUNCTION__, __func__?
sumber
<experimental/source_location>
dalam gcc-9 saat ini.Saya menggunakannya sepanjang waktu. Satu-satunya hal yang saya khawatirkan adalah memberikan IP dalam file log. Jika nama fungsi Anda benar-benar bagus, Anda mungkin membuat rahasia dagang lebih mudah terungkap. Ini seperti pengiriman dengan simbol debug, hanya lebih sulit untuk menemukan sesuatu. Dalam 99,999% kasus tidak ada hal buruk yang akan terjadi.
sumber
strings
utilitas untuk mengekstrak semua data seperti string dari yang dapat dieksekusi. Bahkan executable terkompresi dapat diekstraksi. Berhati-hatilah dengan apa yang Anda kirim ke situs pelanggan. Sering kali pesaing mampu mendapatkan yang dapat dieksekusi Anda, meskipun mereka tidak seharusnya melakukannya.