"Inline" kalit so'zidan Cda qanday foydalanish mumkin?

Javobni inline ga tegishli stackoverflow haqida bir nechta savolni o'qidim, ammo bu haqda hali aniq emas.

  1. static inline void f(void) {} has no practical difference with static void f(void) {}.
  2. inline void f(void) {} in C doesn't work as the C++ way. How does it work in C?
  3. What actually does extern inline void f(void); do?

Men hech qachon C dasturlarida inline kalit so'zidan foydalanishni topmadim va bu kalit so'zni boshqa odamlar kodida ko'rsam, u deyarli har doim statik inline faqat static bilan farq yo'q.

23
"C inline kalit so'zidan qanday foydalaniladi?" - hech narsa.
qo'shib qo'ydi muallif The Paramagnetic Croissant, manba
Bu savollar sizning barcha shubhalaringizga javob beradi ... stackoverflow.com/questions/1759300/…
qo'shib qo'ydi muallif Ali786, manba

5 javoblar

C kodi ikki jihatdan optimallashtirilishi mumkin: Kod hajmi va bajarilishi uchun.

Inline vazifalari:

gcc.gnu.org says,

Inline funktsiyasini e'lon qilish orqali, ushbu funksiyani tezroq chaqirish uchun GCC ni yuborishingiz mumkin. Bir tomondan, GCC ushbu vazifani kodini qidiruvchilar uchun kodga integratsiya qilish uchun erishish mumkin. Bu funktsiya-chaqiruvni hisobga olishni bartaraf etish orqali bajarishni tezroq bajaradi; Bundan tashqari, agar haqiqiy dalillar qiymatlaridan biri qat'iy bo'lsa, ularning ma'lum qiymatlari kompilyatsiya vaqtida soddalashtirishga ruxsat berishi mumkin, shuning uchun inline funktsiyaning barcha kodlari kiritilmasligi kerak. Kod hajmiga ta'siri kamroq prognozli; </body> </body>

Shunday qilib, kompilyatorga funktsiyani bajarish vaqtini yaxshilash niyatida ishlatiladigan kodni yaratish uchun aytiladi.

Agar siz bayroqni o'rnatish yoki tozalash kabi kichik funktsiyalarni e'lon qilsangiz, bu ketma-ketlikda inline deb nomlangan bir necha bitli o'tishni o'zgartirsa, u vaqtga nisbatan katta ishlash ko'rsatkichini o'zgartirishi mumkin, lekin kodning kattaligi bo'yicha.


statik bo'lmagan inline va statik inline

Shunga qaramay gcc.gnu.org

Inline funktsiyasi statik bo'lmasa, derleyici boshqa manbalardan olingan fayllar bo'lishi mumkinligini taxmin qilish kerak; chunki global ramz har qanday dasturda bir marta aniqlanishi mumkin, funktsiya boshqa manba fayllarida aniqlanmasligi kerak, shuning uchun u erda qo'ng'iroqlar birlashtirilmaydi. Shuning uchun, statik bo'lmagan inline funktsiyasi odatdagi usulda har doim o'z-o'zidan tuziladi.


extern inline?

Shunga qaramay, gcc.gnu.org hammasi shunday deydi:

Agar funktsiya ta'rifida ichki va tashqi qiymatni aniqlasangiz, u holda belgilash faqat inlining uchun ishlatiladi. Hech qanday holatda funktsiya o'z manziliga yozilmasa ham, o'z-o'zidan tuzilgan. Bunday manzil faqat tashqi funktsiyaga aylanadi, xuddi siz faqat funktsiyani e'lon qildingiz va uni aniqlab olmadingiz.

Inline va externning bu birikmasi deyarli so'lning ta'siriga ega. Buni ishlatish usuli ushbu kalit so'zlar bilan nom faylida funktsiya ta'rifini qo'yish va kutubxona faylida identifikatsiyaning boshqa nusxasini (inline va extern) yo'q qilishdir. Header fayli ta'rifi inobatga olinadigan funktsiyaga eng ko'p chaqiruvlarga sabab bo'ladi. Agar funktsiyaning har qanday foydasi saqlanib qolsa, ular kutubxonadagi yagona nusxaga murojaat qiladilar.


Xulosa qilish uchun:

  1. inline void f (void) {} ​​uchun inline ta'rifi faqat joriy tarjima birligida amal qiladi.
  2. statik inline void f (void) {} ​​uchun Saqlash klassi static bo'lgani uchun, identifikatorning ichki aloqasi bor va inline ta'rifi boshqa tarjimalar bo'limlarida ko'rinmas.
  3. extern inline void f (void) uchun Saqlash klassi extern bo'lgani uchun identifikatorning tashqi aloqasi bor va inline ta'rifi tashqi ta'rifni ham beradi.
13
qo'shib qo'ydi
Buni faqat tushunaman.
qo'shib qo'ydi muallif Saleh Enam Shohag, manba
Bu yerda javob birdan, bu darhol mantiqqa to'g'ri keldi.
qo'shib qo'ydi muallif byxor, manba

Eslatma: ushbu javobda .c fayllari va .h fayllari haqida gapirganda kodingizni to'g'ri kodladingiz, ya'ni .c Fayllar faqat .h fayllarini o'z ichiga oladi. Turli xilki, .h fayli bir nechta tarjima birliklariga kiritilishi mumkin.

statik inline void f (void) {} ​​ statik void f (void) {} ​​ bilan farq qilishi mumkin emas.

ISO C da, bu to'g'ri. Ular, xatti-harakatlarda bir xil (agar siz ularni bir xil TUda boshqacha qilib aytganda qayta-qayta e'lon qilmasangiz kerak!), Faqat amaliy ta'sir derjerni boshqacha tarzda optimallashtirishga olib kelishi mumkin.

inline void f (void) {} ​​ ning C da C ++ usulida ishlamaydi. Qanday qilib u Cda ishlaydi? extern inline void f (void); nima qilish kerak?

Buni bu javobni va bu ish zarrachalar .

ISO C va C ++ da siz turli xil sabablar bilan bo'lsa-da, bosh kodlardagi inline void f (void) {} ​​ dan foydalanishingiz mumkin!

ISO C da, u hech qanday tashqi ta'rifni bermaydi. ISO C ++ da u tashqi ta'riflarni beradi; lekin C ++ da qo'shimcha qoidalar mavjud (bu C emas), agar inline funktsiyasining bir nechta tashqi ta'rifi mavjud bo'lsa, derleyici uni tartibga soladi va ulardan birini tanlaydi.

extern inline void f(void); in a .c file in ISO C is meant to be paired with the use of inline void f(void) {} in header files. It causes the external definition of the function to be emitted in that translation unit. If you don't do this then there is no external definition, and so you may get a link error (it is unspecified whether any particular call of f links to the external definition or not).

Boshqacha aytganda, ISO C da tashqi belgilash qaerga ketganini qo'lda tanlashingiz mumkin; yoki har bir joyda statik inline yordamida tashqi ta'rifni butunlay bostiradi; ammo ISO C ++ da derleyici tashqi tanlovni qayerda va qayerda tanlashni tanlaydi.

GNU C da narsalar boshqacha (quyida batafsilroq).

Bundan tashqari, GNU C ++ kodlari C ++ kodida statik inline kodini extern inline yozishga imkon beradi ... Men buni aynan qaysi

C dasturlari ichidagi kalit so'zni hech qachon topa olmadim va bu kalit so'zni boshqa odamlar kodi bilan ko'rsam, u deyarli har doim statik inline

Ko'pgina kodlayıcılar nima qilayotganlarini bilishmaydi va ishlash uchun paydo bo'lgan narsalarni birlashtiradi. Bu erda yana bir omil sizning kodingiz ISO C emas, balki GNU C uchun yozilgan bo'lishi mumkin.

GNU C , tekis inline da ISO Sga nisbatan boshqacha munosabatda. , shuning uchun ikkita tarjima bo'limidan olingan tekis inline funktsiyasiga ega .h fayli mavjudligi aniqlanmagan xatti-harakatga olib keladi.

Agar kodlayıcı GNU C'de inline optimallashtirish haqida maslahat berishni istasa, statik inline kerak. statik inline har ikkala ISO C va GNU C da ishlayotganligi sababli, odamlar bu muammolarni bartaraf etishni to'xtatib qo'yishdi va xatoliklarsiz ishlamoqchi ekanligini ko'rishgan.

, faqat statik bilan farq qilmayman.

Farqi shundaki, kompilyatorga tezlikni oshiruvchi hajmni optimallashtirish haqida maslahat berish maqsadga muvofiq. Zamonaviy kompilyatorlar bilan bu ortiqcha.

11
qo'shib qo'ydi
.c faylida extern inline void f (void); ;
fayllaridagi statik inline void f (void) {} ​​ . static kodini olib tashlamasligingiz kerakmi?
qo'shib qo'ydi muallif xiver77, manba
Men faqat "C" tarjima birligidagi funktsiyani bajarish uchun barcha fayllar miqdori haqidagi deklaratsiyalarni externdan tashqari inline funksiya identifikatoriga kiritilgan bo'lsa, u holda ushbu tarjima bo'limidagi ta'rif inline belgilaydi. bu funktsiya uchun tashqi tavsifni ta'minlamaydi va boshqa tarjima birligida tashqi ta'rifni taqiqlamaydi. " Bu satr ichidagi ta'rifning talablariga javob beradigan bo'lsam extern deklaratsiyasi kerak emasligini anglatadimi?
qo'shib qo'ydi muallif xiver77, manba
Endi tushundim. Shunday qilib, extern deklaratsiyasi holda, derleyici ichki satr ichidagi ta'rifni ishlatsa, men bog'laydigan xatoliklarni olmasligim mumkin, lekin derleyici tashqi tanlovni tanlagan bo'lsa, bog'laydigan xatolarini olaman. Men faqat gcc bilan optimallashtirilgan holda va test qildim. Optimisiz holda, tashqi ta'rifga ega bo'lmaganligi uchun bog'lanuvchi xatolikni olaman.
qo'shib qo'ydi muallif xiver77, manba
@ xiver77 siz static ni olib tashlash haqida siz haqsiz; Hozir men standartni qayta o'qib chiqdim va boshqa kanonik javoblardan birini tushunib yetdim. "Funktsiya chaqiruvi inline ta'rifi yoki tashqi ta'rifni ishlatadimi, aniqlanmagan". Faqat tashqi kodli funksiyalarga tegishli bo'lgan murojaatlarga nisbatan qo'llaniladi, shuning uchun statik inline ga qo'ng'iroqlar tashqaridan aniqlangan versiyasi. (Bu, menimcha, kompilyatorga butun dasturni optimallashtirish qilish uchun to'siq qo'yish)
qo'shib qo'ydi muallif M.M, manba
Sizning so'nggi savolingizda nimani anglatishini aniq bilmayman. Agar TUda extern void f (void) holda inline void f (void) {} ​​ bo'lsa, u ham inline ta'rifi, ham tashqi aloqasi funktsiyaga chaqiruvlar ushbu TU ning inline belgilari o'rniga tashqi ta'rifga bog'liq bo'lishi mumkin.
qo'shib qo'ydi muallif M.M, manba
@ xiver77 Ha, bu tovushlar, masalan, bu savolni
qo'shib qo'ydi muallif M.M, manba

C11 funktsiyalarida 6.7.4 funktsiyalarining identifikatorlari dan

6 Inline funksiya identifikatori bilan e'lon qilingan funktsiya ichki satr   funktsiyasi. Funktsiyani inline funktsiyasini bajarish, unga qo'ng'iroqlarni taklif qiladi   funktsiya imkon qadar tez bo'lishi kerak. 138)   Bunday takliflar samarali hisoblanadi    amalga oshirilgan dastur . 139)

     

138) Misol uchun odatdagi funktsiya chaqiruviga muqobil foydalanish orqali   mexanizm, masalan, inline substitution . Inline o'zgarishi emas   matndagi o`zgarish va yangi funksiya yaratmagan. Shuning uchun,   Masalan, tananing ichki qismida ishlatiladigan so'lning kengayishi   funktsiyasi tanadagi funktsiyani belgilashda foydalanadi   funktsiya chaqirilmasa, paydo bo'ladi; va identifikatorlarni nazarda tutadi   Tana sodir bo'lgan joylardagi deklaratsiyalarga. Xuddi shunday   funktsiyasi bir satr ichidagi raqamlardan qat'i nazar bitta manzilga ega   tashqariga qo'shimcha ravishda yuzaga keladigan belgilaydi   .

     

139) Masalan, dastur amalga oshirilishi mumkin    inline substitusionni hech qachon bajarmaslik yoki faqat inline bajarishi mumkin   satr ichidagi xabarnomalar doirasidagi chaqiruvlarga almashtirish.

Ushbu funksiya keng qo'llanilganligi va ushbu funktsiyani chaqirishda tezlikni tanlashni talab qiladigan derleyici taklif qiladi. Zamonaviy aqlli kompilyatorlar yordamida bu juda kam yoki ahamiyatsiz bo'lishi mumkin, chunki kompilyatorlar funksiyaning kiritilishi kerakligini aniqlay olishi mumkin va foydalanuvchilarning inline so'rovini e'tiborsiz qoldirishi mumkin, chunki zamonaviy kompilyatorlar funksiyalarni qanday chaqirish haqida juda samarali qaror qabul qilishlari mumkin.

statik inline void f (void) {} ​​ statik   void f (void) {} ​​.

Ya'ni, zamonaviy kompozitorlar bilan ko'pincha hech qachon. Har qanday kompilyatorlar bilan no amaliy/kuzatiladigan chiqish farqlari mavjud.

inline void f (void) {} ​​ ning C da C ++ usulida ishlamaydi. Qanday qilib?   C da ishlash kerakmi?

Har qanday bir joyga kiradigan funktsiya C ++ ning har bir joyida inline bo'lishi kerak, va linker bir nechta aniqlikdagi xatolardan shikoyat qilmaydi (ta'rif bir xil bo'lishi kerak).

External inline void f (void) aslida nima; nima qilish kerak?

Bu tashqi kodni f ga taqdim etadi. Boshqa kompilyatsiya birligida f mavjud bo'lishi sababli, derleyici chaqiruvlarni tezlashtirish uchun turli xil qo'ng'iroq mexanizmini tanlashi mumkin yoki inline ni butunlay e'tiborsiz qoldirishi mumkin.

4
qo'shib qo'ydi

As a word "Inline" say "In" "Line", adding this keyword to function affects the program in runtime , when a program is compiled ,the code written insides function is pasted under the function call , as function calls are more costly than inline code, so this optimizes the code. So, static inline void f(void) {} and static void f(void) {} , in this inline keyword do makes difference in runtime. But when function has too many lines of code then it won't effect runtime. If you add static before function , function's life time is the life time of the whole program. And that function use is restricted to that file only. To know about extern you can refer to - Effects of the extern keyword on C functions

3
qo'shib qo'ydi
inline kalit so'zini birinchi marta kompilyatorlarga qo'shilganda (birinchi S standartidan ancha oldin), bu uning niyati edi. Biroq, uning mazmuni va ishlatilishi bundan buyon juda ko'p narsalarni o'zgartirdi.
qo'shib qo'ydi muallif M.M, manba

Barcha deklaratsiyalar (jumladan ta'rifi) inline va hech qachon eskiradigan funksiya Shu tarjima birligida ta'rif bo'lishi kerak. Standart bu satr ichidagi atamani ifodalaydi Mustaqil ob'ektlar kodi chiqarilmaydi, shuning uchun bu ta'rif boshqa tarjima birligidan chaqirilmaydi.

Ushbu misolda barcha deklaratsiyalar va ta'riflar inline, lekin externdan foydalanmaydi:

// a declaration mentioning inline     
inline int max(int a, int b);

// a definition mentioning inline  
inline int max(int a, int b) {  
  return a > b ? a : b;  
}

Here is a reference which can give you more clarity on the inline functions in C & also on the usage of inline & extern.

2
qo'shib qo'ydi