Kapan saya harus menulis kata kunci 'inline' untuk fungsi / metode?

562

Kapan saya harus menulis kata kunci inlineuntuk fungsi / metode dalam C ++?

Setelah melihat beberapa jawaban, beberapa pertanyaan terkait:

  • Kapan saya tidak boleh menulis kata kunci 'inline' untuk fungsi / metode dalam C ++?

  • Kapan kompiler tidak tahu kapan membuat fungsi / metode 'inline'?

  • Apakah masalah jika aplikasi multithreaded ketika seseorang menulis 'inline' untuk suatu fungsi / metode?

Sebagian
sumber
40
Jika Anda mendefinisikan suatu fungsi di header, Anda harus mendeklarasikannya sebaris. Kalau tidak, Anda akan mendapatkan kesalahan linker tentang beberapa definisi fungsi.
Martin York
15
@ Martin: Kecuali jika itu dalam definisi kelas, pilih-pilih.
David Thornley
20
@ David: Untuk menjadi pemilih ekstra, itu hanya karena fungsi tersebut ditandai secara implisit inline(9.3 / 2).
Lightness Races dalam Orbit
Juga lihat Fungsi Inline di C ++ FAQ. Mereka memiliki perawatan inline yang sangat baik.
jww

Jawaban:

882

Oh man, salah satu kencing kesayangan saya.

inlinelebih seperti staticatau externdari pada arahan yang memberitahu kompiler untuk menampilkan fungsi Anda. extern, static, inlineAdalah arahan linkage, digunakan hampir secara eksklusif oleh linker, bukan compiler.

Dikatakan bahwa inlinemengisyaratkan kepada kompiler bahwa Anda pikir fungsi tersebut harus diuraikan. Itu mungkin benar pada tahun 1998, tetapi satu dekade kemudian kompiler tidak membutuhkan petunjuk seperti itu. Belum lagi manusia biasanya salah dalam hal mengoptimalkan kode, sehingga sebagian besar penyusun mengabaikan abaikan 'petunjuk'.

  • static- nama variabel / fungsi tidak dapat digunakan di unit terjemahan lainnya. Linker perlu memastikan bahwa itu tidak sengaja menggunakan variabel / fungsi yang ditentukan secara statis dari unit terjemahan lain.

  • extern- gunakan nama variabel / fungsi ini dalam unit terjemahan ini tetapi jangan mengeluh jika itu tidak didefinisikan. Linker akan mengatasinya dan memastikan semua kode yang mencoba menggunakan simbol eksternal memiliki alamatnya.

  • inline- fungsi ini akan didefinisikan dalam beberapa unit terjemahan, jangan khawatir tentang hal itu. Linker perlu memastikan semua unit terjemahan menggunakan instance variabel / fungsi tunggal.

Catatan: Secara umum, menyatakan templat inlinetidak ada gunanya, karena sudah memiliki semantik tautan inline. Namun, spesialisasi eksplisit dan instantiasi templat perluinline digunakan.


Jawaban khusus untuk pertanyaan Anda:

  • Kapan saya harus menulis kata kunci 'inline' untuk fungsi / metode dalam C ++?

    Hanya ketika Anda ingin fungsi tersebut didefinisikan di header. Lebih tepatnya hanya ketika definisi fungsi dapat muncul dalam beberapa unit terjemahan. Ini adalah ide yang baik untuk mendefinisikan fungsi-fungsi kecil (seperti dalam satu liner) dalam file header karena memberikan kompiler lebih banyak informasi untuk bekerja sambil mengoptimalkan kode Anda. Ini juga meningkatkan waktu kompilasi.

  • Kapan saya tidak boleh menulis kata kunci 'inline' untuk fungsi / metode dalam C ++?

    Jangan tambahkan inline hanya karena Anda pikir kode Anda akan berjalan lebih cepat jika kompiler menyatukannya.

  • Kapan kompiler tidak tahu kapan membuat fungsi / metode 'inline'?

    Secara umum, kompiler akan dapat melakukan ini lebih baik daripada Anda. Namun, kompiler tidak memiliki opsi untuk kode inline jika tidak memiliki definisi fungsi. Dalam kode optimal yang dioptimalkan biasanya semuaprivate metode diuraikan apakah Anda memintanya atau tidak.

    Sebagai tambahan untuk mencegah penyatuan dalam GCC, gunakan __attribute__(( noinline )), dan di Visual Studio, gunakan __declspec(noinline).

  • Apakah masalah jika suatu aplikasi multithreaded ketika seseorang menulis 'inline' untuk suatu fungsi / metode?

    Multithreading tidak memengaruhi inlining dengan cara apa pun.

deft_code
sumber
172
+1 Deskripsi inline terbaik yang pernah saya lihat di ... (selamanya). Sekarang saya akan merobek Anda dan menggunakan ini di semua penjelasan saya tentang kata kunci inline.
Martin York
6
@ Ziggy, apa yang saya coba katakan adalah kompilator inlining dan inlinekata kunci tidak terkait. Anda punya ide yang tepat. Sebagai aturan, menebak apa yang akan diperbaiki dengan inlining sangat rentan kesalahan. Pengecualian untuk aturan itu menjadi satu baris.
deft_code
4
Jawaban ini sedikit membingungkan saya. Anda mengatakan semua itu tentang kompiler yang dapat inline / bukan inline hal yang lebih baik. Kemudian Anda mengatakan bahwa Anda harus meletakkan satu fungsi liners / kecil di header, dan bahwa kompiler tidak dapat inline kode tanpa definisi fungsi. Bukankah ini agak kontradiktif? Mengapa tidak meletakkan saja semuanya dalam file cpp dan membiarkan kompilator memutuskan?
user673679
5
Kompiler hanya akan memanggil fungsi inline di mana definisi tersedia di situs panggilan. Meninggalkan semua fungsi dalam file cpp akan membatasi inlining ke file itu. Saya sarankan mendefinisikan satu baris kecil di dalam. H karena biaya untuk kecepatan kompilasi diabaikan dan Anda hampir dijamin kompiler akan sebaris panggilan. Maksud saya tentang compiler inlining adalah bahwa itu adalah port dari seni optimasi hitam, di mana kompiler Anda jauh lebih baik daripada Anda.
deft_code
8
Setiap kali saya membaca sesuatu di akun pengetahuan kumulatif internet, saya harus memikirkan kutipan terkenal John Lawton: Ironi dari Era Informasi adalah bahwa ia telah memberikan penghormatan baru kepada pendapat yang kurang informasi.
IInspectable
60

Saya ingin berkontribusi pada semua jawaban hebat di utas ini dengan contoh yang meyakinkan untuk membubarkan kesalahpahaman yang tersisa.

Diberikan dua file sumber, seperti:

  • inline111.cpp:

    #include <iostream>
    
    void bar();
    
    inline int fun() {
      return 111;
    }
    
    int main() {
      std::cout << "inline111: fun() = " << fun() << ", &fun = " << (void*) &fun;
      bar();
    }
  • inline222.cpp:

    #include <iostream>
    
    inline int fun() {
      return 222;
    }
    
    void bar() {
      std::cout << "inline222: fun() = " << fun() << ", &fun = " << (void*) &fun;
    }

  • Kasus A:

    Kompilasi :

    g++ -std=c++11 inline111.cpp inline222.cpp

    Keluaran :

    inline111: fun() = 111, &fun = 0x4029a0
    inline222: fun() = 111, &fun = 0x4029a0

    Diskusi :

    1. Walaupun Anda harus memiliki definisi identik fungsi inline Anda, kompiler C ++ tidak menandainya jika bukan itu masalahnya (sebenarnya, karena kompilasi terpisah ia tidak memiliki cara untuk memeriksanya). Adalah tugas Anda sendiri untuk memastikan ini!

    2. Linker tidak mengeluh tentang Aturan Satu Definisi , sebagaimana fun()dinyatakan sebagai inline. Namun, karena inline111.cpp adalah unit terjemahan pertama (yang sebenarnya memanggil fun()) yang diproses oleh kompiler, kompiler instantiate fun()setelah pertemuan-panggilan pertamanya di inline111.cpp . Jika kompiler memutuskan untuk tidak memperluas fun()panggilannya dari tempat lain di program Anda ( mis. Dari inline222.cpp ), panggilan ke fun()akan selalu ditautkan ke turunannya yang dihasilkan dari inline111.cpp (panggilan ke fun()dalam inline222.cpp)mungkin juga menghasilkan sebuah instance di unit terjemahan itu, tetapi itu akan tetap tidak terhubung). Memang, itu terbukti dari hasil &fun = 0x4029a0cetakan yang identik .

    3. Akhirnya, terlepas dari inlinesaran kepada kompiler untuk benar - benar memperluas satu-liner fun(), ia mengabaikan saran Anda sepenuhnya, yang jelas karena fun() = 111di kedua baris.


  • Kasus B:

    Kompilasi (perhatikan urutan terbalik) :

    g++ -std=c++11 inline222.cpp inline111.cpp

    Keluaran :

    inline111: fun() = 222, &fun = 0x402980
    inline222: fun() = 222, &fun = 0x402980

    Diskusi :

    1. Kasus ini menegaskan apa yang telah dibahas dalam Kasus A .

    2. Perhatikan poin penting, bahwa jika Anda komentar panggilan sebenarnya untuk fun()di inline222.cpp ( misalnya komentar keluar coutpernyataan-di inline222.cpp benar-benar) kemudian, meskipun urutan kompilasi unit terjemahan Anda, fun()akan dipakai pada itu pertemuan pertama panggilan di inline111.cpp , menghasilkan print-out untuk Kasus B sebagai inline111: fun() = 111, &fun = 0x402980.


  • Kasus C:

    Kompilasi (pemberitahuan -O2) :

    g++ -std=c++11 -O2 inline222.cpp inline111.cpp

    atau

    g++ -std=c++11 -O2 inline111.cpp inline222.cpp

    Keluaran :

    inline111: fun() = 111, &fun = 0x402900
    inline222: fun() = 222, &fun = 0x402900

    Diskusi :

    1. Seperti dijelaskan di sini , -O2optimasi mendorong compiler untuk benar-benar memperluas fungsi yang dapat inline (Perhatikan juga bahwa -fno-inlineadalah standar tanpa opsi optimasi). Seperti terbukti dari cetakan di sini, fun()sebenarnya telah diperluas sebaris (sesuai dengan definisi dalam unit terjemahan tertentu ), menghasilkan dua cetakan yang berbeda fun() . Meskipun demikian, hanya ada satu contoh terkait global fun()(seperti yang dipersyaratkan oleh standar), seperti yang terbukti dari hasil cetak yang identik &fun .
Alaroff
sumber
8
Jawaban Anda adalah posting ilustratif mengapa bahasa membuat inlinefungsi seperti itu menjadi perilaku yang tidak terdefinisi.
R Sahu
Anda juga harus menambahkan kasus di mana kompilasi dan penautan terpisah, dengan masing .cpp- masing menjadi unit terjemahannya sendiri. Lebih disukai, tambahkan case untuk -fltodiaktifkan / dinonaktifkan.
syockit
Referensi C ++ secara eksplisit mengatakan "Jika fungsi inline atau variabel (karena C ++ 17) dengan hubungan eksternal didefinisikan secara berbeda di unit terjemahan yang berbeda, perilaku tidak terdefinisi.". Jadi, hal-hal yang Anda tulis adalah spesifik GCC karena merupakan efek samping dari pengaturan proses kompilasi dan tautan. Juga, perhatikan bahwa ini mungkin berbeda antar versi.
Petr Fiedler
27

Anda masih perlu secara jelas menyejajarkan fungsi Anda saat melakukan spesialisasi template (jika spesialisasi ada dalam file .h)

BostonLogan
sumber
21

1) Saat ini, hampir tidak pernah. Jika itu adalah ide bagus untuk sebaris fungsi, kompiler akan melakukannya tanpa bantuan Anda.

2) Selalu. Lihat # 1.

(Diedit untuk mencerminkan bahwa Anda membagi pertanyaan Anda menjadi dua pertanyaan ...)

Aric TenEyck
sumber
Iya. Inline hanya merupakan petunjuk bagi kompiler, dan bebas untuk mengabaikan Anda. Saat ini kompiler mungkin tahu lebih baik daripada programmer yang fungsinya paling baik untuk inline.
Mark Byers
1
Ya, tetapi kurang relevan - untuk fungsi yang akan diuraikan, tubuh itu harus berada di unit kompilasi yang sama (misalnya, di header). Itu kurang umum dalam program C.
Michael Kohne
1
mendefinisikan templat fungsi non-anggota (alias templat fungsi non-statis) tidak memerlukan inline. Lihat satu aturan definisi (3.2 / 5).
deft_code
2
-1: inlinemasih diperlukan, misalnya untuk mendefinisikan fungsi dalam file header (dan itu diperlukan untuk menguraikan fungsi tersebut di beberapa unit kompilasi).
Melebius
1
@ Étienne itu khusus implementasi. Per standar, ada One Definition Rule, yang berarti di sini bahwa jika Anda secara naif memasukkan definisi fungsi di beberapa unit terjemahan, Anda akan mendapatkan kesalahan. Tetapi jika fungsi tersebut memiliki inlinespecifier, instansnya secara otomatis diciutkan menjadi satu oleh linker, dan ODR tidak digunakan.
Ruslan
12

Kapan saya tidak boleh menulis kata kunci 'inline' untuk fungsi / metode dalam C ++?

Jika fungsi tersebut dideklarasikan di header dan didefinisikan dalam .cppfile, Anda tidak boleh menulis kata kunci.

Kapan kompiler tidak tahu kapan membuat fungsi / metode 'inline'?

Tidak ada situasi seperti itu. Kompiler tidak dapat membuat fungsi sebaris. Yang bisa dilakukan hanyalah menyisipkan beberapa atau semua panggilan ke fungsi. Ia tidak dapat melakukannya jika belum memiliki kode fungsi (dalam hal ini penghubung perlu melakukannya jika ia mampu melakukannya).

Apakah masalah jika suatu aplikasi multithreaded ketika seseorang menulis 'inline' untuk suatu fungsi / metode?

Tidak, itu tidak masalah sama sekali.

Johannes Schaub - litb
sumber
Ada beberapa kasus di mana pantas untuk menggunakan inline dalam file .cpp. Misalnya menerapkan optimisasi pada kode yang sepenuhnya implementasi spesifik.
Robin Davies
@RobinDavies memperbarui jawaban. Sepertinya Anda salah mengerti apa yang ingin saya tulis.
Johannes Schaub - litb
5
  • Kapan kompiler tidak tahu kapan membuat fungsi / metode 'inline'?

Ini tergantung pada kompiler yang digunakan. Jangan percaya secara membabi buta bahwa kompiler saat ini lebih tahu daripada manusia cara inline dan Anda tidak boleh menggunakannya untuk alasan kinerja, karena itu adalah arahan tautan daripada petunjuk pengoptimalan. Sementara saya setuju bahwa secara ideologis argumen-argumen ini benar menghadapi kenyataan mungkin merupakan hal yang berbeda.

Setelah membaca beberapa utas di sekitar saya mencoba rasa ingin tahu efek inline pada kode saya hanya bekerja dan hasilnya adalah saya mendapat speedup terukur untuk GCC dan tidak ada kecepatan untuk kompiler Intel.

(Lebih detail: simulasi matematika dengan beberapa fungsi kritis yang didefinisikan di luar kelas, GCC 4.6.3 (g ++ -O3), ICC 13.1.0 (icpc -O3); menambahkan sebaris ke titik-titik kritis yang menyebabkan peningkatan + 6% dengan kode GCC).

Jadi, jika Anda memenuhi syarat GCC 4.6 sebagai kompiler modern, hasilnya adalah arahan inline masih penting jika Anda menulis tugas intensif CPU dan tahu di mana sebenarnya hambatannya.

meda beda
sumber
6
Saya ingin melihat lebih banyak bukti untuk mendukung klaim Anda. Harap berikan kode yang Anda uji dengan serta hasil assembler dengan dan tanpa kata kunci inline. Sejumlah hal dapat memberi Anda manfaat kinerja.
void.pointer
1
Akhirnya seseorang yang tidak hanya mengulangi apa yang orang lain katakan, tetapi benar-benar memverifikasi pernyataan itu. Gcc memang masih menganggap kata kunci sebaris sebagai petunjuk (saya pikir dentang mengabaikannya sepenuhnya).
MikeMB
@ void.pointer: Mengapa ini sulit dipercaya? Jika pengoptimal sudah sempurna, maka versi baru tidak dapat meningkatkan kinerja program. Tetapi mereka melakukannya secara teratur.
MikeMB
3

Pada kenyataannya, hampir tidak pernah. Yang Anda lakukan hanyalah menyarankan agar kompiler membuat fungsi yang diberikan sebaris (mis., Ganti semua panggilan ke fungsi ini / di badannya). Tidak ada jaminan, tentu saja: kompiler dapat mengabaikan arahan.

Kompiler umumnya akan melakukan pekerjaan yang baik untuk mendeteksi + mengoptimalkan hal-hal seperti ini.

DarkSquid
sumber
7
Masalahnya adalah yang inlinememiliki perbedaan semantik dalam C ++ (misalnya dalam cara beberapa definisi diperlakukan), yang penting dalam beberapa kasus (misalnya templat).
Pavel Minaev
4
inline digunakan untuk menyelesaikan kasus di mana simbol memiliki banyak definisi. Namun template sudah ditangani oleh bahasa. Satu pengecualian adalah fungsi templat khusus yang tidak memiliki parameter templat lagi (templat <>). Ini diperlakukan lebih seperti fungsi daripada templat dan karenanya membutuhkan kata kunci inline untuk menautkan.
deft_code
2

gcc secara default tidak sebaris fungsi apa pun ketika kompilasi tanpa optimasi diaktifkan. Saya tidak tahu tentang studio visual - deft_code

Saya memeriksa ini untuk Visual Studio 9 (15.00.30729.01) dengan mengkompilasi dengan / FAcs dan melihat kode perakitan: Kompiler menghasilkan panggilan ke fungsi anggota tanpa optimasi diaktifkan di mode debug . Bahkan jika fungsi ditandai dengan __forceinline , tidak ada kode runtime inline yang diproduksi.

Jedzia
sumber
1
Aktifkan / Dinding untuk diberi tahu tentang fungsi mana yang ditandai inline tetapi tidak benar-benar
diuraikan
0

Anda ingin memasukkannya di awal, sebelum kembali ketik. Tetapi kebanyakan Compiler mengabaikannya. Jika sudah ditentukan, dan memiliki blok kode yang lebih kecil, sebagian besar kompiler menganggapnya sebaris.

Jeremy Morgan
sumber
0

Kecuali jika Anda menulis perpustakaan atau memiliki alasan khusus, Anda dapat melupakan inlinedan menggunakan pengoptimalan waktu tautan . Ini menghapus persyaratan bahwa definisi fungsi harus di header untuk itu dipertimbangkan untuk digariskan di seluruh unit kompilasi, yang persis apa yang inlinememungkinkan.

(Tapi lihat apakah ada alasan mengapa tidak menggunakan optimasi waktu tautan? )

n.caillou
sumber
0

Kata kunci sebaris meminta kompiler untuk mengganti panggilan fungsi dengan badan fungsi, ia pertama-tama mengevaluasi ekspresi dan kemudian berlalu. Ini mengurangi overhead panggilan fungsi karena tidak perlu menyimpan alamat pengirim dan memori tumpukan tidak diperlukan untuk fungsi argumen.

Kapan harus menggunakan:

  • Untuk Meningkatkan kinerja
  • Untuk mengurangi overhead panggilan.
  • Karena ini hanya permintaan ke kompiler, fungsi-fungsi tertentu tidak akan digariskan * fungsi-fungsi besar
    • fungsi memiliki terlalu banyak argumen kondisional
    • kode rekursif dan kode dengan loop dll.
Sheetal
sumber
Mungkin bermanfaat bagi Anda untuk mengetahui bahwa ini sebenarnya bukan masalahnya. Level optimisasi -O0 hingga - Ofast adalah yang menentukan apakah suatu fungsi digariskan atau tidak. Inline pada kompilasi reguler (-O0) tidak akan inline fungsi terlepas dari apakah Anda menggunakan inlineatau tidak di C dan C ++. C Inline: stackoverflow.com/a/62287072/7194773 C ++ inline: stackoverflow.com/a/62230963/7194773
Lewis Kelsey
0

C ++ inline benar-benar berbeda dengan C inline .

#include <iostream>
extern inline int i[];
int i [5];
struct c {
  int function (){return 1;} //implicitly inline
  static inline int j = 3; //explicitly inline
};
int main() {
  c j;
  std::cout << i;
}

inlinesendiri mempengaruhi compiler, assembler dan linker. Ini adalah arahan ke kompiler yang mengatakan hanya memancarkan simbol untuk fungsi / data ini jika digunakan dalam unit terjemahan, dan jika ya, maka seperti metode kelas, beri tahu assembler untuk menyimpannya di bagian .section .text.c::function(),"axG",@progbits,c::function(),comdatatau .section .bss.i,"awG",@nobits,i,comdatuntuk data. Instansiasi template juga masuk dalam grup comdat mereka sendiri.

Berikut ini .section name, "flags"MG, @type, entsize, GroupName[, linkage]. Misalnya, nama bagiannya adalah .text.c::function(). axGberarti bagian tersebut dapat dialokasikan, dapat dieksekusi, dan dalam sebuah grup yaitu nama grup akan ditentukan (dan tidak ada bendera M sehingga tidak ada entsize yang akan ditentukan); @progbitsberarti bagian tersebut berisi data dan tidak kosong; c::function()adalah nama grup dan grup tersebutcomdatketerkaitan artinya dalam semua file objek, semua bagian yang ditemukan dengan nama grup ini yang ditandai dengan comdat akan dihapus dari executable final kecuali untuk 1 yaitu kompiler memastikan bahwa hanya ada satu definisi dalam unit terjemahan dan kemudian memberitahu assembler untuk menempatkan itu dalam grup sendiri di file objek (1 bagian dalam 1 grup) dan kemudian linker akan memastikan bahwa jika ada file objek memiliki grup dengan nama yang sama, maka hanya memasukkan satu di final .exe. Perbedaan antarainlinedan tidak menggunakan inlinesekarang terlihat oleh assembler dan akibatnya linker, karena itu tidak disimpan dalam .dataatau biasa.text dll oleh assembler karena arahan mereka.

static inlinedalam sebuah kelas berarti ini merupakan definisi tipe dan bukan deklarasi (memungkinkan anggota statis untuk didefinisikan dalam kelas) dan membuatnya inline; sekarang berperilaku seperti di atas.

static inlinepada lingkup file hanya memengaruhi kompiler. Ini berarti ke kompiler: hanya memancarkan simbol untuk fungsi / data ini jika digunakan dalam unit terjemahan dan melakukannya sebagai simbol statis biasa (menyimpan in.text /.data tanpa direktif .globl). Untuk assembler sekarang tidak ada perbedaan antara staticdanstatic inline

extern inlineadalah deklarasi yang berarti Anda harus mendefinisikan simbol ini di unit terjemahan atau melempar kesalahan kompiler; jika sudah didefinisikan maka perlakukan sebagai reguler inlinedan untuk assembler dan linker tidak akan ada perbedaan antara extern inlinedan inline, jadi ini hanya penjaga kompiler.

extern inline int i[];
extern int i[]; //allowed repetition of declaration with incomplete type, inherits inline property
extern int i[5]; //declaration now has complete type
extern int i[5]; //allowed redeclaration if it is the same complete type or has not yet been completed
extern int i[6]; //error, redeclaration with different complete type
int i[5]; //definition, must have complete type and same complete type as the declaration if there is a declaration with a complete type

Keseluruhan di atas tanpa garis kesalahan runtuh menjadi inline int i[5]. Jelas jika Anda melakukan extern inline int i[] = {5};ituextern akan diabaikan karena definisi eksplisit melalui penugasan.

inlinedi namespace, lihat ini dan ini

Lewis Kelsey
sumber
-1

Saat mengembangkan dan men-debug kode, tinggalkan inline. Ini menyulitkan debugging.

Alasan utama untuk menambahkannya adalah untuk membantu mengoptimalkan kode yang dihasilkan. Biasanya ini memperdagangkan ruang kode yang meningkat untuk kecepatan, tetapi terkadang inlinemenghemat ruang kode dan waktu eksekusi.

Mengeluarkan pemikiran seperti ini tentang optimasi kinerja sebelum penyelesaian algoritma adalah optimasi prematur .

wallyk
sumber
12
inlinefungsi biasanya tidak digarisbawahi kecuali dikompilasi dengan optimisasi, sehingga tidak mempengaruhi debugging dengan cara apa pun. Ingat bahwa itu adalah petunjuk, bukan permintaan.
Pavel Minaev
3
gcc secara default tidak sebaris fungsi apa pun ketika kompilasi tanpa optimasi diaktifkan. Saya tidak tahu tentang visual studio
deft_code
Saya bekerja pada proyek g ++ yang sangat besar yang telah mengaktifkan debugging. Mungkin opsi lain mencegahnya, tetapi inlinefungsinya diselaraskan. Tidak mungkin untuk menetapkan breakpoint yang berarti di dalamnya.
wallyk
2
mengaktifkan debugging tidak berhenti inlining di gcc. Jika ada optimasi jika diaktifkan (-O1 atau lebih besar), maka gcc akan mencoba menyejajarkan kasus yang paling jelas. Secara tradisional GDB mengalami kesulitan dengan breakpoints dan konstruktor terutama konstruktor inline. Tapi, itu telah diperbaiki dalam versi terbaru (setidaknya 6,7, mungkin lebih cepat).
deft_code
2
Menambahkan inlinetidak akan melakukan apa pun untuk meningkatkan kode pada kompiler modern, yang dapat menentukan apakah akan inline atau tidak dengan sendirinya.
David Thornley
-1

Kapan seseorang harus sebaris:

1. Ketika seseorang ingin menghindari overhead dari hal-hal yang terjadi ketika fungsi disebut seperti parameter passing, transfer kontrol, kontrol kembali dll.

2.Fungsi harus kecil, sering dipanggil dan membuat inline benar-benar menguntungkan karena sesuai aturan 80-20, cobalah untuk membuat fungsi inline yang memiliki dampak besar pada kinerja program.

Seperti yang kita ketahui bahwa inline hanyalah permintaan untuk mengkompilasi mirip dengan mendaftar dan itu akan dikenakan biaya pada ukuran kode objek.

Ashish
sumber
"Inline hanyalah sebuah permintaan untuk kompiler yang mirip dengan mendaftar" Mereka mirip karena tidak ada permintaan atau ada hubungannya dengan optimasi. inlinetelah kehilangan statusnya sebagai petunjuk optimasi, dan kebanyakan kompiler hanya menggunakannya untuk membuat kelonggaran untuk beberapa definisi - sebagaimana IMO seharusnya. Lebih dari itu, sejak C ++ 11, registertelah sepenuhnya ditinggalkan karena makna sebelumnya dari 'Saya tahu lebih baik daripada kompiler bagaimana mengoptimalkan': itu sekarang hanya kata yang dipesan tanpa makna saat ini.
underscore_d
@underscore_d: Gcc masih mendengarkan sampai inlinetaraf tertentu.
MikeMB
-1

Fungsi C ++ inline adalah konsep yang kuat yang biasa digunakan dengan kelas. Jika suatu fungsi inline, kompiler menempatkan salinan kode dari fungsi itu di setiap titik di mana fungsi dipanggil pada waktu kompilasi.

Setiap perubahan ke fungsi sebaris dapat meminta semua klien dari fungsi tersebut untuk dikompilasi ulang karena kompiler harus mengganti semua kode sekali lagi jika tidak akan dilanjutkan dengan fungsi lama.

Untuk inline suatu fungsi, tempatkan inline kata kunci di depan nama fungsi dan tentukan fungsi sebelum panggilan dilakukan ke fungsi. Compiler dapat mengabaikan kualifikasi inline jika fungsi yang didefinisikan lebih dari satu baris.

Definisi fungsi dalam definisi kelas adalah definisi fungsi inline, bahkan tanpa menggunakan inline specifier.

Berikut ini adalah contoh, yang menggunakan fungsi inline untuk mengembalikan maksimal dua angka

#include <iostream>

using namespace std;

inline int Max(int x, int y) { return (x > y)? x : y; }

// Main function for the program
int main() {
   cout << "Max (100,1010): " << Max(100,1010) << endl;

   return 0;
}

untuk informasi lebih lanjut lihat di sini .

amirfg
sumber