Кіріспе

C және C++ бағдарламалау тілдеріндегі функциялар
C және C++ бағдарламалау тілдеріндегі желілік функциялар

C және C++ бағдарламалау тілдерінде желілік функция – `inline` кілт сөзімен белгіленген функция; ол екі мақсатқа қызмет етеді:
Біріншіден, ол компиляторға функцияның денесін тікелей кодқа ауыстыруды ұсынатын (бірақ міндеттемейтін) директива болып табылады, яғни функцияны шақыру орнына оның кодын енгізу арқылы функция шақыруға кеткен уақытты үнемдейді. Бұл жағынан ол `register` сақтау класы спецификаторына ұқсас, ол да оңтайландыру бойынша кеңес береді. Желілік функцияның екінші мақсаты – байланыс мінез-құлқын өзгерту, бірақ бұл мәселе өте күрделі. Бұл C/C++ тілдеріндегі жеке компиляция және байланыс үлгісіне байланысты қажет, себебі функцияның анықтамасы (коды) оны пайдаланатын барлық модульдерде қайталанған болуы керек. Бұл компиляция кезінде желілік кеңейтуге мүмкіндік береді. Егер функцияның сыртқы байланысы болса, байланыс кезінде қақтығыс туындауы мүмкін (сыртқы символдардың бірегейлігі бұзылады). C және C++ (сондай-ақ GNU C және Visual C++ сияқты түрлері) осы мәселені әртүрлі жолдармен шешеді.

С99

C99 стандартында сызықтық түрде анықталған функция ешқашан, ал сыртқы сызықтық түрде анықталған функция әрқашан сырттан көрінетін функцияны шығарады. C++ стандартынан айырмашылығы, аударма бірліктері арасында бөлісілген сырттан көрінетін функцияны қажет болған жағдайда ғана шығаруға рұқсат жоқ. Егер сызықтық декларациялар сыртқы сызықтық декларациялармен немесе біліктіліксіз декларациялармен (яғни, сызықтық белгішесі немесе сақтау класы жоқ) қосылса, аударма бірлігінде міндетті түрде анықтама болуы керек (біліктіліксіз, сызықтық немесе сыртқы сызықтық) және оған сәйкес сырттан көрінетін функция шығарылады. Сызықтық түрде анықталған функция бағдарламаның басқа бір жерінде сол аттас бір функцияның болуын қажет етеді, ол сыртқы сызықтық түрде немесе біліктіліксіз анықталған болуы керек. Егер бағдарламаның барлық бөлігінде осындай бірнеше анықтама берілсе, байланыстырушы қайталанатын символдар туралы шағымданады. Егер мұндай анықтама болмаса, байланыстырушы міндетті түрде шағымдана бермейді, себебі барлық қолданылулар сызықтық түрде енгізілген болса, ол қажет емес. Бірақ ол шағымдануы мүмкін, өйткені компилятор әрқашан сызықтық белгішені назарға алмауға және функцияға шақыруларды жасауға болады, әсіресе код оптимизацияланбаған кезде. (Бұл қажетті мінез-құлық болуы мүмкін, егер функцияның барлық жерде міндетті түрде сызықтық түрде енгізілуі керек болса және олай болмаса қате туындауы керек.) Ыңғайлы тәсіл – сызықтық функцияларды бас файлдарда анықтау және әр функция үшін бір c файлды құру, онда оның сыртқы сызықтық декларациясы және тиісті бас файлды анықтамасымен қосу. Декларацияның «қосудан» бұрын немесе кейін болуы маңызды емес. Функцияның барлық қолданылулары сызықтық түрде енгізілген жағдайда, соңғы орындалатын файлға қолжетімсіз кодтың қосылуын болдырмау үшін gnu89 сыртқы сызықтық функцияны біліктіліксіз функция ретінде қайта анықтауға рұқсат беретінін ескеру қажет. Ал C99 сызықтық түрде қайта анықтауға рұқсат бермейді. Осылайша, gnu89 extern inline қайта анықталмағанда C99 inline сияқты, ал gnu89 inline болса C99 extern inline сияқты; басқаша айтқанда, gnu89 стандартында сызықтық деп анықталған функция әрқашан және сыртқы сызықтық деп анықталған функция ешқашан сырттан көрінетін функцияны шығара алмайды. Мұның себебі – бұл айнымалыларға ұқсас, олар сыртқы деп анықталғанда ешқашан жадта орын алмайды, ал сыртқы деп анықталмағанда әрқашан жадта орын алады. C99 стандартының себебі керісінше, егер сызықтық түрін пайдалану функцияның сызықтық емес нұсқасын әрқашан шығаруға әкелетін қосымша әсерге ие болса, бұл таңқаларлық болар еді, бұл оның атауынан көрінетін нәрсеге қайшы келеді. Сызықтық функциялар үшін дәл бір сырттан көрінетін функцияның болуын қажет ету және одан туындайтын қолжетімсіз код мәселесі туралы C99 ескертулері gnu89 стандартына да қатысты. gcc компиляторының 4.2 нұсқасына дейін және оның ішінде std=c99 нақты көрсетілген жағдайда да gnu89 сызықтық семантикасын қолданды. 5-ші нұсқада бұл Unix C компиляторларының бастапқыланбаған жаһандық айнымалылардың сыртқы емес анықтамалары үшін дәстүрлі мінез-құлқына сәйкес келеді.