Yanıtlar:
inlinederleyiciye, gerçek bir çağrı yürütmek yerine işlev içeriğini çağıran koda yerleştirmeyi denemesini söyler.
Sıklıkla çağrılan küçük işlevler için büyük bir performans farkı yaratabilir.
Ancak, bu sadece bir "ipucu" ve derleyici bunu göz ardı edebilir ve çoğu derleyici, mümkün olduğu durumlarda, optimizasyonların bir parçası olarak anahtar kelime kullanılmadığında bile "satır içi" yapmaya çalışacaktır.
Örneğin:
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*/};
Bu sıkı döngü, her yinelemede bir işlev çağrısı gerçekleştirir ve işlev içeriği aslında derleyicinin çağrıyı gerçekleştirmek için koyması gereken koddan önemli ölçüde daha azdır. inlinetemelde derleyiciye yukarıdaki kodu eşdeğerine dönüştürmesi talimatını verecektir:
int i;
....
for (i=0; i<999999; i = i+1) { /* do something here */};
Gerçek işlev çağrısını atlama ve geri dönme
Açıkçası bu, gerçek bir kod parçası değil, noktayı gösteren bir örnektir.
statickapsamı ifade eder. C'de bu, işlevin / değişkenin yalnızca aynı çeviri birimi içinde kullanılabileceği anlamına gelir.
static(olsun veya olmasın inline) başlıkta gayet iyi olabilir, neden olmasın. Şablonlar C ++ içindir, bu soru C ile ilgilidir
inlineiyi bir stildir, imo
inline vermez . Yalnızca programcının işlev gövdesini ODR ihlali olmadan çoklu çeviri birimlerine dahil etmesine izin verir. Bunun bir yan etkisi 's markaları mümkün derleyicisi için, bu zaman olacağı ediyorum işlevi satır içi aslında bunu yapmak için.
Varsayılan olarak, bir satır içi tanım yalnızca mevcut çeviri biriminde geçerlidir.
Depolama sınıfı ise extern, tanımlayıcının harici bağlantısı vardır ve satır içi tanım da harici tanımı sağlar.
Depolama sınıfı ise static, tanımlayıcının dahili bağlantısı vardır ve satır içi tanım diğer çeviri birimlerinde görünmezdir.
Depolama sınıfı belirtilmemişse, satır içi tanım yalnızca geçerli çeviri biriminde görülebilir, ancak tanımlayıcının hala harici bir bağlantısı vardır ve farklı bir çeviri biriminde bir dış tanım sağlanmalıdır. İşlev mevcut çeviri birimi içinde çağrılırsa, derleyici satır içi veya harici tanımı kullanmakta serbesttir.
Derleyici, tanımı mevcut çeviri biriminde görülebilen (ve bağlantı zamanı optimizasyonları sayesinde, farklı çeviri birimlerinde bile olsa, satır içi (ve satır içi değil) herhangi bir işlevi satır içi (ve satır içi olmamak) konusunda özgür olduğundan, C standardı gerçekten hesaba katmaz. that), çoğu pratik amaç için, staticve static inlineişlev tanımları arasında hiçbir fark yoktur .
inline(Gibi belirteci registerdepolama sınıfına) sadece bir derleyici ipucu ve derleyici tümüyle görmezden serbesttir. Standartlara uyumlu, optimize etmeyen derleyiciler yalnızca yan etkilerini dikkate almalıdır ve derleyicilerin optimize edilmesi, bu optimizasyonları açık ipuçları olsun veya olmasın yapacaktır.
inlineve registerprogramcı optimizasyonları imkansız hale getirecek kod yazdığında derleyiciye hatalar atması talimatını verdikleri için faydasız değildir: Harici bir inlinetanım iç bağlantıya sahip tanımlayıcılara referans veremez (çünkü bunlar farklı bir çeviri biriminde mevcut olmayacaktır) veya statik depolama süresi olan değiştirilebilir yerel değişkenler tanımlayın (çünkü bunlar, çeviri birimleri arasında durumu paylaşmazlar) ve register-kalifiye değişkenlerin adreslerini alamazsınız.
Kişisel olarak, üstbilgi dosyalarına işlev tanımlarını koymanın ana nedeni onları satır içi yapmak olduğundan, staticişlev tanımlarını başlıklarda işaretlemek inlineiçin de kullanıyorum.
Genel olarak, başlıklardaki bildirimlere ek olarak yalnızca static inlineişlev ve static constnesne tanımlarını kullanıyorum extern.
Daha önce inlinedepolama sınıfından farklı bir işlev yazmadım static.
inlineGerçekte satır içi yapmaya uygulanmış gibi konuşan herhangi bir cevap yanıltıcıdır ve muhtemelen yanlıştır. Hiçbir modern derleyici bunu satır içi bir ipucu olarak kullanmaz veya bir işlevin satır içi olarak yazılmasını sağlamak için bunu gerektirmez.
staticve arasındaki anlamsal farkı anlamadım static inline. Her ikisi de tanımı diğer çeviri birimlerine görünmez kılar. Peki static inlinebunun yerine yazmak için mantıklı bir neden ne olabilir static?
GCC ile olan deneyimlerime dayanarak bunu biliyorum staticve static inlinederleyicinin kullanılmayan işlevler hakkında nasıl uyarılar verdiğini bir şekilde farklılaştırıyorum. Daha doğrusu, staticişlevi bildirdiğinizde ve mevcut çeviri biriminde kullanılmadığında, derleyici kullanılmayan işlev hakkında uyarı üretir, ancak bu uyarıyı olarak değiştirerek engelleyebilirsiniz static inline.
Bu nedenle, bunun staticçeviri birimlerinde kullanılması gerektiğini ve kullanılmayan işlevleri bulmak için derleyicinin fazladan kontrolünden faydalanması gerektiğini düşünüyorum . Ve static inlineuyarı veren olmadan kaplı (nedeniyle dış bağlantı bulunmadığı için) olabilir işlevleri sağlamak için başlık dosyalarında kullanılmalıdır.
Ne yazık ki bu mantık için herhangi bir kanıt bulamıyorum. GCC belgelerinden bile, inlinekullanılmayan işlev uyarılarını engellediğine karar veremedim . Birisi bunun açıklamasına bağlantılar paylaşırsa memnun olurum.
warning: unused function 'function' [clang-diagnostic-unused-function]bir static inlineişlev var clang-tidy. Ama kesinlikle, bu en iyi açıklamalardan biri ve static& inline!
C'de, statictanımladığınız işlev veya değişkenin yalnızca bu dosyada kullanılabileceği anlamına gelir (yani derleme birimi)
Yani, static inlineyalnızca bu dosyada kullanılabilen satır içi işlevi anlamına gelir.
DÜZENLE:
Derleme birimi Çeviri Birimi olmalıdır
the compile unittranslation unit
Dil düzeyinde değil, popüler uygulama düzeyinde olan bir fark: gcc'nin belirli sürümleri, static inlinevarsayılan olarak referans alınmayan işlevleri çıktıdan kaldırır , ancak staticbaşvurulmasa bile düz işlevleri korur. Emin bu geçerli olduğu hangi versiyonları değilim, ama pratik bir bakış açısından o her zaman kullanmak iyi bir fikir olabilir demektir inlineiçin staticbaşlıklardaki fonksiyonlar.
inlineTanım olarak kullanmaya ne dersiniz ? Bunu externişlevler için kullanmamayı da ima ediyor musunuz ?
attribute((used))asm'nin başka türlü başvurulmayan staticişlevlere ve verilere başvurmasına izin vermek için geçmişine ve kullanımına bakarak öğrenebilirsiniz .
statickapsamı ifade eder. C'de bu, işlevin / değişkenin yalnızca aynı çeviri birimi içinde kullanılabileceği anlamına gelir.