C++ menambah kata kunci sebaris yang boleh memberi awalan definisi fungsi, seperti:
inline int max_int( int a, int b ) { return a > b ? a : b; }
untuk memberi pengkompil "petunjuk" bahawa program secara keseluruhan mungkin mendapat manfaat dalam prestasi daripada fungsi yang disertakan.
Fungsi yang telah disebari telah dikembangkan kodnya pada setiap titik ia dipanggil dan bukannya melaksanakan mekanisme panggilan fungsi biasa:
Untuk fungsi sangat kecil, inlining boleh menghasilkan peningkatan prestasi. Tetapi seperti kebanyakan perkara lain, terdapat pertukaran.
Kata kunci sebaris telah dialihkan kembali ke C99, tetapi dengan keperluan yang sedikit berbeza — lebih kemudian.
Fungsi sebaris adalah seperti (dan bertujuan untuk menggantikan banyak kegunaan) makro seperti fungsi. Secara amnya, ini adalah perkara yang baik kerana fungsi sebaris adalah fungsi dan mempunyai semantik fungsi penuh dan bukannya penggantian teks semata-mata yang dilakukan oleh prapemproses yang tidak memahami sama ada C atau C++.
Makro yang setara dengan fungsi max_int():
#define MAX_INT(A,B) A > B ? A : B /* bad implementation */
mempunyai masalah berikut:
Selain itu, makro:
Fungsi sebaris tidak mempunyai masalah ini namun boleh menghasilkan manfaat prestasi yang sama. Oleh itu, gunakan fungsi sebaris dan bukannya makro seperti fungsi.
Seperti yang dinyatakan, menyatakan sebaris adalah hanya "petunjuk" kepada pengkompil bahawa program secara keseluruhan mungkin mendapat manfaat dalam prestasi daripada fungsi yang diselaraskan. Pengkompil bebas untuk mengabaikan petunjuk.
Kenapa? Kerana terdapat kes apabila ia sama ada idea yang baik atau mustahil. Fungsi sama ada tidak sebaris atau lazimnya tidak sebaris apabila mana-mana satu daripada yang berikut adalah benar:
Mungkin ada sebab lain. Semuanya sangat bergantung pada fungsi, hujahnya, pengkompil dan apa sahaja pilihan yang diberikan kepadanya.
Jika pengkompil sama ada tidak boleh atau memilih untuk tidak menyelaraskan fungsi, ia tidak memberi amaran kepada anda bahawa ia tidak melakukannya (secara lalai). Sesetengah penyusun, cth., gcc, mempunyai pilihan -Winline yang akan memberi amaran kepada anda dan memberi anda sebab mengapa fungsi tidak diselaraskan.
Menentukan sebaris adalah serupa dengan kod lama yang menentukan daftar — kedua-duanya hanyalah petunjuk.
Untuk kebanyakan fungsi, sebahagian besar kos melaksanakan fungsi adalah dalam badan fungsi, bukan dalam mekanisme panggilan fungsi. Oleh itu, untuk membolehkan sesuatu fungsi menjadi calon yang baik untuk sebaris, ia secara amnya mestilah:
Apabila ragu-ragu, profilkan kod anda. Menggunakan sebaris adalah bukan kata kunci ajaib "buat saya lebih pantas". Selain itu, penggunaan sebaris yang berlebihan boleh menyebabkan penyimpangan kod yang juga menjadikan prestasi program anda lebih teruk secara keseluruhan.
Untuk maklumat lanjut, lihat Penyakit sebaris.
Fungsi yang sering menjadi calon yang baik untuk inlining termasuk:
Fungsi sebaris yang ideal kedua-duanya meningkatkan prestasi dan mengurangkan saiz kod.
Walau bagaimanapun, satu kaveat untuk mana-mana fungsi sebaris ialah jika takrifannya berubah, ia memerlukan penyusunan semula semua kod yang menggunakannya.
Jika fungsi sebaris sebenarnya diselaraskan oleh pengkompil, maka, sebagai tambahan kepada menghapuskan kod untuk mekanisme panggilan fungsi biasa, pengkompil juga mungkin dapat:
In order for the compiler to be able to inline a function, it has to be able to “see” its definition (not just its declaration) in every .c or .cpp file it’s used in just like a macro. Hence, an inline function must be defined in a header file.
Normally, a function, like everything else, must have exactly one definition by adhering to the one definition rule (ODR). However, since the definition of an inline function is “seen” in multiple .c or .cpp files, the ODR is suspended for that function.
It is possible to have different definitions for inline functions having the same name, but this results in undefined behavior since the compiler has no way to check that every definition is the same.
To inline a function in C++, all you need do is prefix the function definition with inline — that’s it. The compiler and/or linker will automatically discard all but one definition from the final executable file for you.
However, to inline a function in C, you additionally must explicitly tell the compiler into what .o file to put the one definition in the event the compiler is either unable or unwilling to inline a function via extern inline.
For example, in exactly one .c file, you would declare a function like:
// util.c extern inline int max_int( int, int );
That tells the compiler to “put the one definition for max_int() into util.o.”
Alternatively in C, you can instead declare an inline function static also:
static inline int max_int( int a, int b ) { return a > b ? a : b; }
If you do this, then:
Inline functions, if used judiciously, can yield performance gains. Generally, only very small functions are good candidates for inlining.
Starting in C++11, inline functions can alternatively be declared constexpr, but that’s a story for another time.
Atas ialah kandungan terperinci Fungsi Sebaris dalam C dan C++. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!