Bir işlev / yöntem için 'inline' anahtar kelimesini ne zaman yazmalıyım?


562

inlineC ++ 'da bir işlev / yöntem için anahtar kelimeyi ne zaman yazmalıyım ?

Bazı cevapları gördükten sonra, ilgili bazı sorular:

  • Ne zaman gerekir değil C ++ bir işlev / yöntem için anahtar kelime 'inline' yazmak?

  • Derleyici ne zaman bir fonksiyon / yöntem 'inline' yapacağını ne zaman bilemez?

  • Bir işlev / yöntem için 'satır içi' yazıldığında uygulamanın çoklu iş parçacığına sahip olması önemli midir?


40
Bir başlıkta bir işlev tanımlarsanız, bunu satır içinde bildirmeniz gerekir. Aksi takdirde, işlevin çoklu tanımları hakkında bağlayıcı hataları alırsınız.
Martin York

15
@Martin: Sınıf tanımında olmadığı sürece, seçici olmak.
David Thornley

20
@David: Ekstra seçici olmak, bunun nedeni sadece bu tür işlevlerin örtük olarak işaretlenmiş olmasıdır inline(9.3 / 2).
Yörüngedeki Hafiflik Yarışları


Ayrıca C ++ SSS'deki Satır İçi İşlevler konusuna bakın . Satır içi çok iyi bir tedaviye sahiptirler.
jww

Yanıtlar:


882

Ah adamım, evcil hayvanımdan biri.

inlinederleyiciye işlevlerinizi satır içinde yapmasını söyleyen bir yönerge gibi staticya da externdaha fazladır. extern, static, inlineBağlayıcı olmayan derleyici tarafından hemen hemen tamamen bağlanmanın direktifleri vardır.

Söylenir inlinederleyici ipuçları işlev satır içi olmalıdır düşünüyorum. Bu 1998'de doğru olabilir, ancak on yıl sonra derleyicinin böyle bir ipucuna ihtiyacı yoktur. Kod optimizasyonu söz konusu olduğunda insanlar genellikle yanlıştır, bu yüzden çoğu derleyici 'ipucu' görmezden gelir.

  • static- değişken / işlev adı diğer çeviri birimlerinde kullanılamaz. Bağlayıcı, yanlışlıkla başka bir çeviri biriminden statik olarak tanımlanmış bir değişken / işlev kullanmadığından emin olmalıdır.

  • extern- bu çeviri biriminde bu değişken / işlev adını kullanın ancak tanımlanmadıysa şikayet etmeyin. Bağlayıcı onu sıralar ve bazı extern sembollerini kullanmaya çalışan tüm kodların adreslerinin bulunduğundan emin olur.

  • inline- Bu işlev birden fazla çeviri biriminde tanımlanacaktır, endişelenmeyin. Bağlayıcının, tüm çeviri birimlerinin değişken / işlevin tek bir örneğini kullandığından emin olması gerekir.

Not: Genel olarak, şablonların bildirilmesi inline, inlinezaten bağlantı semantiğine sahip oldukları için anlamsızdır . Ancak, açık uzmanlaşma ve şablonların örnekleme gerektireninline kullanılacak.


Sorularınıza özel cevaplar:

  • C ++ 'da bir işlev / yöntem için' inline 'anahtar kelimesini ne zaman yazmalıyım?

    Yalnızca işlevin bir başlıkta tanımlanmasını istediğinizde. Daha doğrusu, yalnızca işlevin tanımı birden çok çeviri biriminde gösterilebildiğinde. Üstbilgi dosyasındaki küçük (bir astarda olduğu gibi) işlevleri tanımlamanız iyi olur, çünkü derleyiciye kodunuzu en iyi duruma getirirken daha fazla bilgi verir. Ayrıca derleme süresini de artırır.

  • Ne zaman bir işlev / yöntem için 'inline' anahtar sözcüğünü C ++ 'da yazmamalıyım?

    Derleyici satır içine girerse kodunuzun daha hızlı çalışacağını düşündüğünüz için satır içi eklemeyin.

  • Derleyici ne zaman bir fonksiyon / yöntem 'inline' yapacağını ne zaman bilemez?

    Genel olarak, derleyici bunu sizden daha iyi yapabilir. Ancak, derleyici işlev tanımına sahip değilse satır içi kodlama seçeneğine sahip değildir. Maksimal olarak optimize edilmiş kodda private, ister istemeseniz de istemeseniz de genellikle tüm yöntemler satır içine alınır.

    GCC'de satırlamayı önlemek için bir kenara, kullanın __attribute__(( noinline ))ve Visual Studio'da kullanın __declspec(noinline).

  • Bir işlev / yöntem için 'satır içi' yazıldığında uygulamanın çoklu iş parçacığına sahip olması önemli midir?

    Çoklu iş parçacıkları satırlamayı hiçbir şekilde etkilemez.


172
+1 İçinde gördüğüm satır içi çizginin en iyi açıklaması ... (sonsuza dek). Şimdi sizi kopyalayıp bu satır içi anahtar kelimenin tüm açıklamalarında kullanacağım.
Martin York

6
@Ziggy, söylemeye çalıştığım derleyici satır içi ve inlineanahtar kelime ile ilgili değildi. Yine de doğru fikre sahipsiniz. Kural olarak, satır içi ile neyin geliştirileceğini tahmin etmek hataya yatkındır. Bu kuralın istisnası bir gömlektir.
deft_code

4
Bu cevap beni biraz karıştırıyor. Derleyicinin satır içi şeyleri daha iyi satır içi / satırsız yapabilmesi ile ilgili her şeyi söylüyorsunuz. Ardından, başlığa bir satır / küçük işlev koymanız gerektiğini ve derleyicinin işlev tanımı olmadan kod satır içi yapamayacağını söylersiniz. Bunlar biraz çelişkili değil mi? Neden sadece her şeyi cpp dosyasına koyup derleyicinin karar vermesine izin vermiyorsunuz?
user673679

5
Derleyici, yalnızca tanımın çağrı sitesinde kullanılabildiği yerlerde işlev çağrılarını satır içi yapar. Cpp dosyasındaki tüm işlevleri bırakmak o dosyaya satırlamayı sınırlar. Derleme hızının maliyeti göz ardı edilebilir olduğundan ve derleyicinin çağrıyı satır içinde alacağından neredeyse emin olduğunuz için .h'de küçük bir astar tanımlamayı öneririm. Derleyici satır içi ile ilgili nokta, derleyicinizin sizden çok daha iyi olduğu kara optimizasyon sanatının limanı olmasıdır.
deft_code

8
Ne zaman internetin kümülatif bilgisinin hesabına bir şey okuduğumda , John Lawton'un ünlü sözünü düşünmek zorundayım: Bilgi Çağının ironisi, bilgisiz görüşlere yeni bir saygınlık kazandırmasıdır.
2013

60

Kalan yanlış anlamaları dağıtmak için ikna edici bir örnekle bu konudaki tüm harika cevaplara katkıda bulunmak istiyorum.

Verilen iki kaynak dosyası:

  • 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;
    }

  • Durum A:

    Derleme :

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

    Çıktı :

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

    Tartışma :

    1. Satır içi işlevlerinizle aynı tanımlara sahip olsanız bile, C ++ derleyicisi durum böyle değilse işaretlemez (aslında, ayrı derleme nedeniyle kontrol etmenin bir yolu yoktur). Bunu sağlamak sizin görevinizdir!

    2. Bağlayıcı şikayet etmez Bir Tanımı Kural olarak, fun()ilan edilir inline. Ancak, inline111.cpp (aslında çağıran ilk çeviri birimidir fun()derleyici tarafından işlenen), derleyici başlatır fun()onun üzerine ilk çağrı-karşılaşma inline111.cpp . Derleyici karar verirse değil genişletmek için fun()programınızda başka bir yerde onun çağrısı üzerine ( örn gelen inline222.cpp ), çağrı fun()daima üretilen onun örneğine bağlantılı olacak inline111.cpp (çağrısının fun()inline222.cppbu çeviri biriminde de bir örnek oluşturabilir, ancak bağlantısı kaldırılmış olarak kalır). Gerçekten de, aynı &fun = 0x4029a0çıktılardan açıkça anlaşılmaktadır .

    3. Son olarak, rağmen inlineetmek derleyici öneri aslında genişletmek tek astar fun(), bu görmezden çünkü açıktır tamamen öneri, fun() = 111çizgilerin her ikisi de.


  • Durum B:

    Derleme (ters sıralamaya dikkat edin) :

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

    Çıktı :

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

    Tartışma :

    1. Bu dava, Durum A'da tartışılanları açıklamaktadır .

    2. Eğer gerçek çağrısı açýklama takdirde, önemli bir noktayı dikkat edin fun()içinde inline222.cpp ( örn dışarı comment coutiçinde -Bildirim inline222.cpp çeviri birimlerinin derleme kararına rağmen, daha sonra tamamen) fun()o ilk çağrı karşılaşma var üzerine örneği olacak inline111.cpp , Durum B olarak yazdırılır inline111: fun() = 111, &fun = 0x402980.


  • Durum C:

    Derleme (not -O2) :

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

    veya

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

    Çıktı :

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

    Tartışma :

    1. Burada açıklandığı gibi , -O2optimizasyon, derleyiciyi satır içine alınabilen işlevleri gerçekten genişletmeye teşvik eder ( Optimizasyon seçenekleri olmadan -fno-inlineda varsayılan olarak dikkat edin ). Buradaki ana hattan da anlaşılacağı üzere fun(), aslında satır içi genişletilmiştir ( belirli bir çeviri birimindeki tanımına göre ), iki farklı fun() çıktıya neden olur. Buna rağmen , aynı çıktıdan da anlaşılacağı üzere, küresel olarak bağlantılı (standardın gerektirdiği gibi) yalnızca bir örneği vardır .fun() &fun

8
Yanıtınız, dilin neden bu tür inlineişlevleri tanımsız davranış haline getirdiğinin açıklayıcı bir gönderisidir .
R Sahu

Ayrıca, derleme ve bağlamanın ayrı olduğu, her .cppbirinin kendi çeviri birimi olduğu durumlar eklemeniz gerekir . Tercihen, -fltoetkin / devre dışı durumları ekleyin .
syockit

C ++ başvurusu, "Dış bağlantıya sahip bir satır içi işlev veya değişken (C ++ 17'den beri) farklı çeviri birimlerinde farklı tanımlanmışsa, davranış tanımsızdır." Yani yazdığınız şeyler derleme ve bağlantı süreçlerinin düzenlenmesinin bir yan etkisi olduğu için GCC'ye özgüdür. Ayrıca, bunun sürümler arasında değişiklik gösterebileceğini unutmayın.
Petr Fiedler

27

Şablon uzmanlığı yaparken işlevinizi açıkça satır içi yapmanız gerekir (uzmanlık .h dosyasındaysa)


21

1) Günümüzde, neredeyse hiç. Bir işlevi satır içine almak iyi bir fikirse, derleyici bunu sizin yardımınız olmadan yapacaktır.

2) Her zaman. Bkz.

(Sorunuzu iki soruya böldüğünüzü yansıtmak üzere düzenlendi ...)


Evet. Satır içi derleyiciye sadece bir ipucudur ve sizi görmezden gelmek ücretsizdir. Bu günlerde derleyici muhtemelen hangi işlevlerin satır içinde en iyi olduğunu programcıdan daha iyi bilir.
Mark Byers

1
Evet, ancak daha az alakalı - bir işlevin satır içine alınması için gövdesi aynı derleme biriminde olmalıdır (örneğin, bir başlıkta). Bu C programlarında daha az yaygındır.
Michael Kohne

1
üye olmayan bir işlev şablonu (statik olmayan işlev şablonu olarak da bilinir) satır içi gerektirmez. Bkz. Bir tanım kuralı (3.2 / 5).
usta_code

2
-1: inlineyine de, örneğin bir başlık dosyasındaki bir işlevi tanımlamak için gereklidir (ve bu tür bir işlevi birkaç derleme biriminde satır içine almak için gereklidir).
Melebius

1
@ Étienne, uygulamaya özeldir. Standart olarak, Bir Tanımlama Kuralı vardır, yani burada işlev tanımını çok sayıda çeviri birimine saf bir şekilde eklerseniz bir hata alırsınız. Ancak bu işlevin inlinebelirteci varsa , örnekleri bağlayıcı tarafından otomatik olarak bire daraltılır ve ODR kullanılmaz.
Ruslan

12

Ne zaman bir işlev / yöntem için 'inline' anahtar sözcüğünü C ++ 'da yazmamalıyım?

Fonksiyon başlığında bildirilmiş ve tanımlanmış ise .cppdosyada, sen gerektiğini değil anahtar kelimeyi yazın.

Derleyici ne zaman bir fonksiyon / yöntem 'inline' yapacağını ne zaman bilemez?

Böyle bir durum yok. Derleyici satır içi işlev yapamaz. Yapabileceği tek şey, işleve yapılan bazı veya tüm çağrıları satır içi yapmaktır. Fonksiyonun koduna sahip değilse bunu yapamaz (bu durumda linker bunu yapabiliyorsa yapmalıdır).

Bir işlev / yöntem için 'satır içi' yazıldığında uygulamanın çoklu iş parçacığına sahip olması önemli midir?

Hayır, bu hiç önemli değil.


Satır içi bir .cpp dosyasında kullanılmasının uygun olduğu durumlar vardır. Örneğin, tamamen uygulamaya özel olan koda optimizasyon uygulamak.
Robin Davies

@RobinDavies cevap güncellendi. Yazmak istediğim şeyi yanlış anlamış gibisin.
Johannes Schaub - litb

5
  • Derleyici ne zaman bir fonksiyon / yöntem 'inline' yapacağını ne zaman bilemez?

Bu, kullanılan derleyiciye bağlıdır. Günümüzde derleyicilerin insanlara nasıl satır içi yapılacağını daha iyi bildiğine körü körüne güvenmeyin ve bunu performans nedenleriyle asla kullanmamalısınız, çünkü optimizasyon ipucu yerine bağlantı direktifidir. İdeolojik olarak bu argümanların gerçekle karşılaşma konusunda doğru olduğunu kabul ederken farklı bir şey olabilir.

Etrafında birden fazla iş parçacığı okuduktan sonra ben sadece çalışıyorum kod üzerinde satır içi etkileri denedim ve sonuçları ben GCC için ölçülebilir hızlanma ve Intel derleyici için hız yok oldu.

(Daha fazla detay: sınıf dışında tanımlanan birkaç kritik fonksiyona sahip matematik simülasyonları, GCC 4.6.3 (g ++ -O3), ICC 13.1.0 (icpc -O3); kritik noktalara satır içi eklenmesi GCC kodu ile +% 6 hızlanmaya neden oldu).

GCC 4.6'yı modern bir derleyici olarak nitelendirirseniz, CPU yoğun görevler yazarsanız ve darboğazın tam olarak nerede olduğunu biliyorsanız, satır içi yönerge yine de önemlidir.


6
İddialarınızı destekleyecek daha fazla kanıt görmek istiyorum. Lütfen test ettiğiniz kodu ve satır içi anahtar kelimeyle veya satır içi anahtar kelime olmadan birleştirici çıktısını sağlayın. Size performans avantajları sağlayan çok sayıda şey olabilir.
void.pointer

1
Sonunda sadece başkalarının söylediklerini tekrarlamakla kalmayan, aynı zamanda bu ifadeleri doğrulayan biri. Gcc gerçekten hala satır içi anahtar kelime bir ipucu olarak düşünüyor (sanırım clang tamamen yok sayar).
MikeMB

@ void.pointer: Buna inanmak neden bu kadar zor? Optimize ediciler zaten mükemmel olduysa, yeni sürümler program performansını iyileştiremedi. Ama düzenli olarak yapıyorlar.
MikeMB

3

Gerçekte, neredeyse hiç. Tek yaptığınız, derleyicinin belirli bir işlevi satır içinde yapmasını öneriyor (örn., Bu işleve yapılan tüm çağrıları değiştirin / vücuduyla). Elbette hiçbir garanti yoktur: derleyici yönergeyi görmezden gelebilir.

Derleyici genellikle böyle şeyleri tespit etmek ve optimize etmek için iyi bir iş çıkarır.


7
Sorun, bazı durumlarda (örn. Şablonlar) önemli olan C ++ ' inlineda semantik bir fark olması (örn. Çoklu tanımların ele alınış şekli).
Pavel Minaev

4
satır içi, bir sembolün birden fazla tanımının bulunduğu durumları çözmek için kullanılır. Ancak şablonlar dil tarafından zaten ele alınmıştır. Bir istisna, artık herhangi bir şablon parametresi olmayan özel bir şablon işlevidir (şablon <>). Bunlar şablonlardan çok işlevlere benzer ve bu nedenle bağlantı kurmak için satır içi anahtar kelimeye ihtiyaç duyarlar.
usta_code

2

gcc varsayılan olarak, optimizasyon etkinleştirilmeden derlenirken hiçbir işlevi satır içine almaz. Görsel stüdyo hakkında bir fikrim yok - deft_code

Bunu Visual Studio 9 (15.00.30729.01) için / FAcs ile derleyerek ve derleme koduna bakarak kontrol ettim: Derleyici, hata ayıklama modunda optimizasyon etkinleştirilmeden üye işlevlerine çağrılar üretti . İşlev __forceinline ile işaretlenmiş olsa bile , satır içi çalışma zamanı kodu üretilmez.


1
Satır içinde işaretlenen ancak aslında satır içine
girilmeyen

0

Dönüş tipinden önce, en baştan koymak istersiniz. Ancak çoğu Derleyici bunu görmezden gelir. Tanımlanmışsa ve daha küçük bir kod bloğuna sahipse, çoğu derleyici yine de satır içi olduğunu düşünür.


0

Bir kitaplık yazmadığınız veya özel nedenleriniz olmadıkça, bağlantı zamanı optimizasyonunu unutabilir inlineve kullanabilirsiniz . Bir işlev tanımlamasının, derleme birimleri arasında satır içi işlem için dikkate alınabilmesi için bir başlıkta olması gereksinimini ortadan kaldırır; bu da tam olarak izin verir.inline

(Ancak bkz. Bağlantı süresi optimizasyonunu kullanmamanın bir nedeni var mı? )


0

Satır içi anahtar sözcük, derleyiciden işlev çağrısını işlevin gövdesi ile değiştirmesini ister, önce ifadeyi değerlendirir ve sonra geçer. argümanlar.

Ne zaman kullanılır:

  • Performansı artırmak için
  • Çağrı yükünü azaltmak için.
  • Derleyiciye yapılan bir istek olduğundan, belirli işlevler satır içine alınmaz * büyük işlevler
    • çok fazla koşullu argüman içeren işlevler
    • özyinelemeli kod ve döngüler vb.

Bunun aslında böyle olmadığını bilmek size fayda sağlayabilir. -O0 - - Ofast optimizasyon seviyesi, bir işlevin satır içi olup olmadığını belirleyen şeydir. Düzenli derleme (-O0) satır içi inline, C ve C ++ 'da kullansanız da kullanmasanız da bir satır içi işleve sahip olmayacaktır . C Satır İçi: stackoverflow.com/a/62287072/7194773 C ++ satır içi: stackoverflow.com/a/62230963/7194773
Lewis Kelsey

0

C ++ satır içi, C satır içi öğesinden tamamen farklıdır .

#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;
}

inlinekendi başına derleyici, montajcı ve bağlayıcıyı etkiler. Derleyiciye, çeviri biriminde kullanılıyorsa bu işlev / veri için yalnızca bir sembol yandığını söyleyen bir direktiftir ve eğer öyleyse, sınıf yöntemleri gibi, montajcıya bunları bölüme .section .text.c::function(),"axG",@progbits,c::function(),comdatveya .section .bss.i,"awG",@nobits,i,comdatveri için saklamasını söyleyin .

Bunu takip eder .section name, "flags"MG, @type, entsize, GroupName[, linkage]. Örneğin, bölüm adı .text.c::function(). axGbölümün ayrılabilir, yürütülebilir ve bir grupta olduğu anlamına gelir, yani bir grup adı belirtilecektir (ve M bayrağı yoktur, bu nedenle entsize belirtilmez); @progbitsbölümün veri içerdiği ve boş olmadığı anlamına gelir; c::function()grup adı ve grubun sahip olduğucomdatbağlantı, tüm nesne dosyalarında, comdat ile etiketlenen bu grup adıyla karşılaşılan tüm bölümlerin 1 dışında son yürütülebilir dosyadan kaldırılacağı anlamına gelir; yani derleyici, çeviri biriminde yalnızca bir tanım olduğundan emin olur ve ardından derleyiciye koymasını söyler bunu nesne dosyasında kendi grubunda (1 grupta 1 bölüm) ve daha sonra bağlayıcı herhangi bir nesne dosyası aynı ada sahip bir gruba sahipse, son .exe'de yalnızca bir tane içerdiğinden emin olur. Arasındaki fark inlineve kullanmayan inlinedüzenli yer etmedi, çünkü bağlayıcı assembler için ve sonuç olarak artık görünür .dataya .textdolayı direktiflerine çevirici tarafından vb.

static inlinebir sınıfta bunun bir tür tanımı ve bildirim değil (statik elemanın sınıfta tanımlanmasına izin verir) anlamına gelir ve satır içi olmasını sağlar; şimdi yukarıdaki gibi davranıyor.

static inlinedosya kapsamı yalnızca derleyiciyi etkiler. Derleyici için şu anlama gelir: bu işlev / veri için yalnızca çeviri biriminde kullanılıyorsa ve bunu düzenli bir statik sembol olarak (eğer .globl yönergesi olmadan in.text /.data depola) yapın. Montajcı için şimdi staticve arasında bir fark yoktur.static inline

extern inlinebu sembolü çeviri biriminde tanımlamanız veya derleyici hatası atmanız gerektiği anlamına gelen bir bildirimdir; daha sonra tanımlanan düzenli olarak muamele eğer inlineve çevirici ve ilintileyici orada arasında hiçbir fark olacak extern inlineve inlinebu sadece bir derleyici bekçi yani.

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

Hata çizgisi olmadan yukarıdakilerin tümü çöker inline int i[5]. Açıkçası eğer extern inline int i[] = {5};o zaman externatama yoluyla açık tanımına bağlı olarak göz ardı edilecektir.

inlineBir ad üzerine, bkz bu ve bu


-1

Kod geliştirirken ve hata ayıklarken, inlinedışarıda bırakın . Hata ayıklamayı zorlaştırır.

Bunları eklemenin ana nedeni, oluşturulan kodu optimize etmektir. Tipik olarak bu, hız için kod alanını arttırır, ancak bazen inlinehem kod alanından hem de yürütme süresinden tasarruf sağlar.

Algoritma tamamlanmadan önce performans optimizasyonu hakkında bu tür düşüncelerin alınması, erken optimizasyondur .


12
inlineişlevler, optimizasyonlarla derlenmedikçe genellikle satır içi değildir, bu nedenle hata ayıklamayı hiçbir şekilde etkilemezler. Unutmayın, bir ipucu, bir talep değil.
Pavel Minaev

3
gcc varsayılan olarak, optimizasyon etkinleştirilmeden derlenirken hiçbir işlevi satır içine almaz. Visual studio hakkında bir fikrim yok
deft_code

Hata ayıklamayı etkinleştiren muazzam bir g ++ projesi üzerinde çalıştım. Belki diğer seçenekler bunu engelledi, ancak inlineişlevler satır içine alındı. Onlara anlamlı bir kırılma noktası koymak imkansızdı.
wallyk

2
hata ayıklamanın etkinleştirilmesi gcc'de satır içi durmayı durdurmaz. Etkinleştirildiğinde (-O1 veya daha yüksek) herhangi bir optimizasyon varsa, gcc en belirgin durumları satır içine almaya çalışır. Geleneksel olarak GDB kesme noktaları ve inşaatçılar ile özellikle satır içi inşaatçılar ile zor zamanlar geçirdi. Ancak, bu son sürümlerde düzeltildi (en az 6.7, belki daha erken).
usta_code

2
Ekleme inline, modern bir derleyicideki kodu geliştirmek için hiçbir şey yapmaz, bu da satır içi olup olmadığını anlayabilir.
David Thornley

-1

Ne zaman satır içi olmalıdır:

1. Birisi parametre geçişi, kontrol transferi, kontrol dönüşü vb.

2.Fonksiyon küçük olmalı, sık sık çağrılır ve satır içi yapmak gerçekten avantajlıdır, çünkü 80-20 kuralına göre, bu işlevi program performansı üzerinde büyük etkisi olan satır içi yapmaya çalışın.

Bildiğimiz gibi, satır içi kayıt için benzer derleyici bir istek ve bu nesne kodu boyutuna mal olacak.


"satır içi, yalnızca kayıt işlemine benzer bir derleyici isteğidir" Bunlar benzerdir çünkü ne istek ne de optimizasyonla ilgisi yoktur. inlinebir optimizasyon ipucu olarak statüsünü kaybetti ve çoğu derleyici bunu sadece çoklu tanımlara izin vermek için kullanıyor - IMO'nun olması gerektiği gibi. Dahası, C ++ 11, register'Derleyiciden nasıl optimize edeceğimi daha iyi biliyorum' gibi önceki anlamı için tamamen kullanımdan kaldırıldı: şu anda sadece mevcut anlamı olmayan ayrılmış bir kelime.
underscore_d

@underscore_d: Gcc hala inlinebir dereceye kadar dinliyor .
MikeMB

-1

C ++ satır içi işlevi, sınıflarla yaygın olarak kullanılan güçlü bir kavramdır. Bir işlev satır içi ise, derleyici işlevin derleme zamanında çağrıldığı her noktaya bu işlevin kodunun bir kopyasını yerleştirir.

Satır içi işlevde yapılan herhangi bir değişiklik, derleyicinin tüm kodu bir kez daha değiştirmesi gerektiğinden, işlevin tüm istemcilerinin yeniden derlenmesini gerektirebilir, aksi takdirde eski işlevlerle devam eder.

Bir işlevi satır içine almak için, anahtar kelimeyi işlev adının önüne satır içine yerleştirin ve işleve herhangi bir çağrı yapılmadan önce işlevi tanımlayın. Derleyici, tanımlı işlevin bir satırdan fazla olması durumunda satır içi niteleyiciyi yoksayabilir.

Sınıf tanımındaki işlev tanımı, satır içi belirtici kullanılmadan bile satır içi işlev tanımıdır.

Aşağıda, maksimum iki sayı döndürmek için satır içi işlevi kullanan bir örnek verilmiştir.

#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;
}

daha fazla bilgi için buraya bakınız .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.