IMO keduanya membuat fungsinya hanya memiliki cakupan unit terjemahan.
Apa perbedaan antara fungsi "statis" dan "sebaris statis"?
Kenapa harus inline
di taruh di file header, bukan di .c
file?
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
mengacu pada ruang lingkup. Dalam C itu berarti bahwa fungsi / variabel hanya dapat digunakan dalam unit terjemahan yang sama.static
(dengan atau tanpainline
) bisa di header dengan baik, tidak ada alasan kenapa tidak. Template untuk C ++, pertanyaan ini tentang C.inline
adalah gaya yang baik, imoinline
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
danstatic inline
fungsi.The
inline
specifier (sepertiregister
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
danregister
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 alamatregister
variabel yang memenuhi syarat.Secara pribadi, saya menggunakan konvensi untuk menandai
static
definisi fungsi di dalam header jugainline
, 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 selainextern
deklarasi di dalam header.Saya tidak pernah menulis
inline
fungsi dengan kelas penyimpanan yang berbeda daristatic
.sumber
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
danstatic inline
. Keduanya membuat definisi tersebut tidak terlihat oleh unit terjemahan lain. Jadi apa alasan yang masuk akal untuk menulisstatic inline
daripada menulisstatic
?Dari pengalaman saya dengan GCC, saya mengetahuinya
static
danstatic inline
berbeda dalam hal bagaimana kompilator mengeluarkan peringatan tentang fungsi yang tidak digunakan. Lebih tepatnya ketika Anda mendeklarasikanstatic
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 menjadistatic 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. Danstatic 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.sumber
warning: unused function 'function' [clang-diagnostic-unused-function]
untukstatic inline
fungsi ketika membangun denganclang-tidy
(v8.0.1), yang digunakan di unit lain terjemahan. Tapi yang pasti, ini adalah salah satu penjelasan dan alasan terbaik untuk menggabungkanstatic
&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
sumber
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 mempertahankanstatic
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 digunakaninline
untukstatic
fungsi di header.sumber
inline
definisi? Apakah Anda juga menyiratkan tidak menggunakannya untukextern
fungsi?attribute((used))
dan penggunaannya untuk memungkinkan asm mereferensikanstatic
fungsi dan data yang tidak direferensikan .