Jawaban:
inline
menginstruksikan kompilator untuk mencoba menyematkan konten fungsi ke dalam kode panggilan alih-alih menjalankan panggilan yang sebenarnya.
Untuk fungsi kecil yang sering dipanggil dapat membuat perbedaan performa yang besar.
Namun, ini hanya sebuah "petunjuk", dan kompilator mungkin mengabaikannya, dan sebagian besar kompiler akan mencoba "sebaris" bahkan ketika kata kunci tidak digunakan, sebagai bagian dari pengoptimalan, jika memungkinkan.
sebagai contoh:
static int Inc(int i) {return i+1};
.... // some code
int i;
.... // some more code
for (i=0; i<999999; i = Inc(i)) {/*do something here*/};
Loop ketat ini akan melakukan pemanggilan fungsi pada setiap iterasi, dan konten fungsi sebenarnya jauh lebih kecil daripada kode yang perlu dimasukkan oleh compiler untuk melakukan panggilan. inline
pada dasarnya akan menginstruksikan kompiler untuk mengubah kode di atas menjadi setara dengan:
int i;
....
for (i=0; i<999999; i = i+1) { /* do something here */};
Melewati pemanggilan dan pengembalian fungsi yang sebenarnya
Jelas ini adalah contoh untuk menunjukkan intinya, bukan potongan kode yang sebenarnya.
static
mengacu pada ruang lingkup. Dalam C itu berarti bahwa fungsi / variabel hanya dapat digunakan dalam unit terjemahan yang sama.
static
(dengan atau tanpa inline
) bisa di header dengan baik, tidak ada alasan kenapa tidak. Template untuk C ++, pertanyaan ini tentang C.
inline
adalah gaya yang baik, imo
inline
tidak menginstruksikan kompilator untuk melakukan upaya apa pun dalam menyebariskan. Ini hanya memungkinkan programmer untuk memasukkan badan fungsi dalam beberapa unit terjemahan tanpa pelanggaran ODR. Efek samping dari hal ini adalah memungkinkan kompilator, ketika ia akan menyebariskan fungsi, untuk benar-benar melakukan ini.
Secara default, definisi sebaris hanya valid di unit terjemahan saat ini.
Jika kelas penyimpanannya adalah extern
, pengidentifikasi memiliki hubungan eksternal dan definisi sebaris juga memberikan definisi eksternal.
Jika kelas penyimpanannya adalah static
, pengenal memiliki tautan internal dan definisi sebaris tidak terlihat di unit terjemahan lain.
Jika kelas penyimpanan tidak ditentukan, definisi sebaris hanya terlihat di unit terjemahan saat ini, tetapi pengenal masih memiliki tautan eksternal dan definisi eksternal harus disediakan di unit terjemahan yang berbeda. Kompilator bebas menggunakan definisi inline atau eksternal jika fungsi dipanggil dalam unit terjemahan saat ini.
Karena kompiler bebas untuk menyebariskan (dan tidak menyebariskan) fungsi apa pun yang definisinya terlihat di unit terjemahan saat ini (dan, berkat pengoptimalan waktu tautan, bahkan di unit terjemahan yang berbeda, meskipun standar C tidak benar-benar memperhitungkan that), untuk sebagian besar tujuan praktis, tidak ada perbedaan antara definisi static
dan static inline
fungsi.
The inline
specifier (seperti register
kelas penyimpanan) hanya sedikit compiler, dan compiler gratis untuk benar-benar mengabaikannya. Kompiler non-pengoptimalan yang sesuai standar hanya perlu menghormati efek sampingnya, dan pengoptimal kompiler akan melakukan pengoptimalan ini dengan atau tanpa petunjuk eksplisit.
inline
dan register
bukan tidak berguna, meskipun, karena mereka menginstruksikan compiler untuk melempar kesalahan ketika programmer menulis kode yang akan membuat pengoptimalan menjadi tidak mungkin: inline
Definisi eksternal tidak dapat merujuk pengenal dengan tautan internal (karena ini tidak akan tersedia di unit terjemahan yang berbeda) atau tentukan variabel lokal yang dapat dimodifikasi dengan durasi penyimpanan statis (karena ini tidak akan berbagi status di seluruh unit terjemahan), dan Anda tidak dapat mengambil alamat register
variabel yang memenuhi syarat.
Secara pribadi, saya menggunakan konvensi untuk menandai static
definisi fungsi di dalam header juga inline
, karena alasan utama untuk meletakkan definisi fungsi dalam file header adalah membuatnya tidak dapat dibariskan.
Secara umum, saya hanya menggunakan static inline
static const
definisi fungsi dan objek selain extern
deklarasi di dalam header.
Saya tidak pernah menulis inline
fungsi dengan kelas penyimpanan yang berbeda dari static
.
inline
seolah-olah benar-benar diterapkan pada sebaris adalah menyesatkan dan bisa dibilang salah. Tidak ada kompiler modern yang menggunakannya sebagai petunjuk untuk menyebariskan atau memerlukannya untuk mengaktifkan sebaris suatu fungsi.
static
dan static inline
. Keduanya membuat definisi tersebut tidak terlihat oleh unit terjemahan lain. Jadi apa alasan yang masuk akal untuk menulis static inline
daripada menulis static
?
Dari pengalaman saya dengan GCC, saya mengetahuinya static
dan static inline
berbeda dalam hal bagaimana kompilator mengeluarkan peringatan tentang fungsi yang tidak digunakan. Lebih tepatnya ketika Anda mendeklarasikan static
fungsi dan itu tidak digunakan dalam unit terjemahan saat ini maka compiler menghasilkan peringatan tentang fungsi yang tidak digunakan, tetapi Anda dapat menghambat peringatan itu dengan mengubahnya menjadi static inline
.
Jadi saya cenderung berpikir bahwa static
harus digunakan dalam unit terjemahan dan manfaat dari kompilator cek ekstra tidak untuk menemukan fungsi yang tidak digunakan. Dan static inline
sebaiknya digunakan di file header untuk menyediakan fungsi yang bisa di-line (karena tidak adanya linkage eksternal) tanpa mengeluarkan peringatan.
Sayangnya saya tidak dapat menemukan bukti untuk logika itu. Bahkan dari dokumentasi GCC saya tidak dapat menyimpulkan bahwa inline
menghalangi peringatan fungsi yang tidak digunakan. Saya akan menghargai jika seseorang akan membagikan tautan ke deskripsi itu.
warning: unused function 'function' [clang-diagnostic-unused-function]
untuk static inline
fungsi ketika membangun dengan clang-tidy
(v8.0.1), yang digunakan di unit lain terjemahan. Tapi yang pasti, ini adalah salah satu penjelasan dan alasan terbaik untuk menggabungkan static
& inline
!
Di C, static
berarti fungsi atau variabel yang Anda tentukan hanya dapat digunakan di file ini (yaitu unit kompilasi)
Jadi, static inline
artinya fungsi inline yang hanya bisa digunakan di file ini.
EDIT:
Unit kompilasi haruslah The Translation Unit
the compile unit
ada sesuatu yang saya tulis karena kesalahan, tidak ada hal seperti itu, terminologi sebenarnya adalahtranslation unit
Satu perbedaan yang bukan pada level bahasa tetapi pada level implementasi populer: versi gcc tertentu akan menghapus static inline
fungsi yang tidak direferensikan dari keluaran secara default, tetapi akan mempertahankan static
fungsi biasa meskipun tidak direferensikan. Saya tidak yakin versi mana ini berlaku untuk, tetapi dari sudut pandang praktis itu berarti mungkin ide yang baik untuk selalu digunakan inline
untuk static
fungsi di header.
inline
definisi? Apakah Anda juga menyiratkan tidak menggunakannya untuk extern
fungsi?
attribute((used))
dan penggunaannya untuk memungkinkan asm mereferensikan static
fungsi dan data yang tidak direferensikan .
static
mengacu pada ruang lingkup. Dalam C itu berarti bahwa fungsi / variabel hanya dapat digunakan dalam unit terjemahan yang sama.