Apa perbedaan antara __PRETTY_FUNCTION__
, __FUNCTION__
, __func__
, dan di mana mereka didokumentasikan? Bagaimana cara saya memutuskan mana yang akan digunakan?
sumber
Apa perbedaan antara __PRETTY_FUNCTION__
, __FUNCTION__
, __func__
, dan di mana mereka didokumentasikan? Bagaimana cara saya memutuskan mana yang akan digunakan?
__func__
adalah pengidentifikasi yang dinyatakan secara implisit yang memperluas ke variabel array karakter yang berisi nama fungsi ketika digunakan di dalam suatu fungsi. Itu ditambahkan ke C di C99. Dari C99 §6.4.2.2 / 1:
Pengidentifikasi
__func__
secara implisit dinyatakan oleh penerjemah seolah-olah, segera setelah tanda kurung pembukaan masing-masing definisi fungsi, deklarasistatic const char __func__[] = "function-name";
muncul, di mana fungsi-nama adalah nama dari fungsi leksikal-melampirkan. Nama ini adalah nama fungsi tanpa hiasan.
Perhatikan bahwa ini bukan makro dan tidak memiliki arti khusus selama preprocessing.
__func__
ditambahkan ke C ++ di C ++ 11, di mana ia ditentukan sebagai mengandung "string yang didefinisikan dengan implementasi" (C ++ 11 §8.4.1 [dcl.fct.def.general] / 8), yang tidak cukup seperti berguna sebagai spesifikasi dalam C. (Proposal asli untuk ditambahkan __func__
ke C ++ adalah N1642 ).
__FUNCTION__
adalah ekstensi pra-standar yang didukung oleh beberapa kompiler C (termasuk gcc dan Visual C ++); secara umum, Anda harus menggunakan __func__
mana yang didukung dan hanya digunakan __FUNCTION__
jika Anda menggunakan kompiler yang tidak mendukungnya (misalnya, Visual C ++, yang tidak mendukung C99 dan belum mendukung semua C ++ 0x, tidak menyediakan__func__
).
__PRETTY_FUNCTION__
adalah ekstensi gcc yang sebagian besar sama dengan __FUNCTION__
, kecuali bahwa untuk fungsi C ++ berisi "cantik" nama fungsi termasuk tanda tangan dari fungsi. Visual C ++ memiliki ekstensi yang serupa (tetapi tidak cukup identik) __FUNCSIG__
,.
Untuk makro yang tidak standar, Anda perlu membaca dokumentasi kompiler Anda. Ekstensi Visual C ++ termasuk dalam dokumentasi MSDN dari kompiler C ++ "Predefined Macro" . Ekstensi dokumentasi gcc dijelaskan di halaman dokumentasi gcc "Function Names as Strings."
__FUNCTION__
, keduanya melakukan hal yang sedikit berbeda. gcc memberikan yang setara dengan__func__
. VC memberikan versi nama yang belum didekorasi, tetapi masih menghiasi,. Untuk metode bernama "foo", gcc akan memberi Anda"foo"
, VC akan memberi"my_namespace::my_class::foo"
.__PRETTY_FUNCTION__
muncul di daftar sebagai tersedia dan ketika saya menggerakkan mouse saya di atasnya, itu memang menampilkan informasi tentang nama fungsi, namun gagal untuk dikompilasi.Meskipun tidak sepenuhnya menjawab pertanyaan awal, ini mungkin yang ingin dilihat kebanyakan orang Google.
Untuk GCC:
sumber
__func__
berfungsi saat tertanam di fungsi lain? Katakanlah saya punya function1, tidak perlu argumen. function1 memanggil function2 yang mencakup__func__
, nama fungsi mana yang akan dicetak, 1 atau 2?__func__
ini adalah makro, ia akan menerjemahkan ke fungsi apa pun yang sedang Anda masuki. Jika Anda memasukkannya ke f1 dan memanggil f1 di f2, Anda akan selalu mendapatkan f1.__PRETTY_FUNCTION__
menangani fitur C ++: kelas, ruang nama, templat, dan kelebihanmain.cpp
Kompilasi dan jalankan:
Keluaran:
Anda mungkin juga tertarik dengan jejak tumpukan dengan nama fungsi: cetak panggilan tumpukan di C atau C ++
Diuji di Ubuntu 19.04, GCC 8.3.0.
C ++ 20
std::source_location::function_name
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1208r5.pdf masuk ke C ++ 20, jadi kami masih memiliki cara lain untuk melakukannya.
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:
jadi perhatikan bagaimana ini mengembalikan informasi penelepon, dan karena itu sempurna untuk penggunaan dalam pencatatan, lihat juga: Apakah ada cara untuk mendapatkan nama fungsi di dalam fungsi C ++?
sumber
__func__
didokumentasikan dalam standar C ++ 0x pada bagian 8.4.1. Dalam kasus ini, ini adalah variabel fungsi lokal yang telah ditentukan dari formulir:di mana "nama fungsi" adalah specfic implementasi. Ini berarti bahwa setiap kali Anda mendeklarasikan suatu fungsi, kompiler akan menambahkan variabel ini secara implisit ke fungsi Anda. Hal yang sama berlaku untuk
__FUNCTION__
dan__PRETTY_FUNCTION__
. Meskipun huruf besar mereka, mereka bukan makro. Meskipun__func__
merupakan tambahan untuk C ++ 0xmasih akan mengkompilasi kode menggunakan
__func__
.__PRETTY_FUNCTION__
dan__FUNCTION__
didokumentasikan di sini http://gcc.gnu.org/onlinedocs/gcc-4.5.1/gcc/Function-Names.html#Function-Names .__FUNCTION__
hanyalah nama lain untuk__func__
.__PRETTY_FUNCTION__
sama seperti__func__
di C tetapi di C ++ itu berisi tipe tanda tangan juga.sumber
__func__
bukan bagian dari C ++ 03. Itu telah ditambahkan dalam C ++ 0x, tetapi C ++ 0x belum "standar C ++," masih dalam bentuk konsep.Bagi mereka, yang bertanya-tanya bagaimana hasilnya dalam VS.
Pembaruan 1 MSVC 2015, cl.exe versi 19.00.24215.1:
keluaran:
Menggunakan
__PRETTY_FUNCTION__
pemicu kesalahan pengidentifikasi yang tidak diumumkan, seperti yang diharapkan.sumber