GCC инлайн функция работи толкова бързо, колкото макро, AVR, програмиране

Използвайки вградените функция (инлайн), можете да инструктира GCC да направи функция изисква по-бързо. Един от начините, по които ССЗ могат да постигнат това - да въведете код във функцията на органа, е мястото, където функцията се нарича. Тя се обработва по-бърз процесор, защото тя елиминира разходите за извикване на функция и да се върне от него. Освен това, ако някой от действителните аргументи на функцията е константа, техните известни стойности могат да бъдат взети под внимание по време на компилация, с което може да бъде не построен всички функции на тялото. Резултатът ще бъде, че размерът на кода е по-малко предсказуеми; обектен код може да се увеличи или намали с използването на вградени функции, в зависимост от всеки конкретен случай. Можете също да укажете на ССЗ се опита да интегрира всички "прости достатъчно" функции на мястото на повикване, ако използвате опцията -finline-функции. Това са преводи на членове [1, 2].

GCC реализира 3 различни семантика за обявяване инлайн функции. Един от тях е на разположение с възможност -std = gnu89 или -fgnu89-инлайн, или когато има атрибут за всички инлайн декларации, а другият като използвате опциите -std = C99, -std = C11, -std = gnu99 или -std = gnu11 ( без -fgnu89-вградени), и трета използване на режим на C ++ компилация.

За да заявите вградена функция, използвайте в своята декларация инлайн ключова дума, така:

Ако пишете заглавния файл, плъг-ин програми ISO С90, вместо ключовата дума в текста използване __inline__ (за подробности виж. Box "Подмяна на ключови думи").

Метод razrulit тези въпроси - сложи "__" в началото и в края на всяка ключова дума проблематично. Например, вместо да се използва __asm__ ASM и __inline__ вместо вградени.

Други компилатори C не приемат тези алтернативни ключови думи; Ако искате да компилирате код от друг компилатор, можете да укажете определения за алтернативни ключови думи като макроси, за да ги заменят с потребителски ключови думи. Тя изглежда по следния начин:

Вариант -pedantic а други водят до предупреждения за много разширения GNU C. Можете да изключите тези предупреждения в един израз от написването __extension__ преди изразяването. Изразяване __extension__ няма да има ефект, ако се използва в грешна контекст.

Тези три типа интеграция се държат по този начин в две важни случаи: когато ключовата дума в текста се използва в статични (статично) функция, подобна на примера по-горе, а когато функцията за първи път се обявява, без редови ключова дума, а след това се определя като инлайн, като този :

И в двата случая, програмата се държи същото, както ако не сте използвали редови ключовата дума, с изключение, което се променя със скоростта на изпълнение.

Моля, имайте предвид, че някои използвате определени функции е невъзможно да се вгражда-смяна. Например: variadic-функция (функция с променлив брой аргументи), използване alloca, използва изчислява Гото (. Виж карето "Етикети като стойности"), използването на не-местен Гото, използвайки вложени (вложени) функции използват setjmp, използват __builtin_longjmp и използването __builtin_return или __builtin_apply_args. Вариант -Winline ще ви предупреди за ситуации, при които функцията е маркиран като инлайн, но това не може да се осъществи на вграждането, а също така дава причината за това.

За да използвате тази стойност, трябва да се извърши прехвърлянето за него. Това се прави за оператора изчислената преход (изчислява Иди), Иди * EXP; (1). Например:

Разрешено всеки израз от тип нищожен *.

Един от начините да се използват тези константи - инициализация на статичен масив, който се третира като маса скок:

След това можете да изберете етикет върху индекса, като този:

Имайте предвид, че това няма да бъде направено чрез проверка за излизане извън индекса на масива С никога не се извършва автоматично.

Такъв набор от ценности етикет се използва за същите цели като преминаването на оператора. Въпреки това, преминаването по-ясно да се чете, така че винаги да го използвате вместо набор от етикети, освен в случаите, когато ключът не е подходящ за вашата кандидатура.

Друга употреба на стойности на етикетите - преводач в онлайн код. Етикети в функциите на обвивката могат да бъдат съхранявани в кода поток за ултрабързи разклонения.

Алтернативен начин за писане на предходния пример:

Този код е по-за използване в споделени библиотеки лесен за употреба, тъй като намалява броя на необходимите движения, и следователно позволява използването на данни само за четене. Тази алтернатива на различията в етикетите не се поддържат за процесор AVR, използвайте първата опция за тях.

В съответствие с изискванията на стандарт ISO C ++, каза на функциите ССЗ - членове на класа (т.е., функциите, определени в тялото на класа ..) Маркирано като инлайн, дори ако те не са изрично декларирани с редови ключова дума. Можете да замените това поведение с помощта на -fno-подразбиране-инлайн вариант (за подробности виж. Описание на опции, които контролират диалекта на C ++ [3]).

GCC не вградите всички функции, когато не се направи оптимизация, освен ако посочите always_inline атрибут за функция по следния начин:

Останалата част от този раздел се отнася до включването GNU C90.

Когато инлайн функция не е статичен (не-статични качества), а след това компилаторът трябва да се разбира, че може да има се проведе разговори от други изходни файлове; като глобален символ може да се определи само на едно място в програмата, тази функция не трябва да се дефинира в други изходни файлове, така че не могат да бъдат изградени, че функцията на повиквания. По този начин, не-статични функции са винаги събрани в избрания код, както обикновено.

Тази комбинация от вградени и ученик дава макро ефект. Използвайте метод - постави дефиницията на функцията на тези ключови думи в заглавната част на файла, и поставете друго копие на определението (без редови и ученик) във файл библиотека. Определение в заглавната част на файла ще предизвика най-много обаждания на функцията ще бъде построен. Ако има някаква полза от функции, които ще се харесат на нея като едно копие в библиотеката.

[Вградена функция на езика C в контекста на преносимостта на код]

В точката на прилагане на вградена функция съставител е намек, че трябва да се вземат някои мерки, за да извикате функцията по-бързо, отколкото би направил нормално. Най-често тези действия се състоят в това, че на мястото на обаждането ще замени функция тялото без да се налага да се обадя на оператора. Защото, когато тази замяна не се изисква инструкция да се обадя (повикване) и връщане (задържане) и не е необходимо да се запазят стаковете локалните променливи и се използват регистри, това дава на компилатора да изпълнява определени оптимизации при комбиниране на кодови функции и основната програма.

Има няколко начина, за да се определи най-редово функции; всяка съществуваща дефиниция гледка със сигурност ще създаде самостоятелен обект код или определено не генерира самостоятелно обектен код или да генерирате самостоятелен обект код само, ако знаете, че имате нужда от него. Понякога това може да доведе до дублиране на кода на обект, който е потенциален проблем, поради следните причини:

• се губи паметта.
• Може да доведе до факта, че указатели към една и съща функция не са равни помежду си.
• може да намали ефективността на кеш инструкция (макар и вмъкване също може да се направи по друг начин).

Ако някое от следните е проблем за вас, можете да използвате стратегията да заобиколят код дублиране. Тя просто се обсъжда в статията.

Турският бизнес единица разбере отделен модул (файл) изходния код на C. статични функции и статични променливи са специални правила за обхват се прилагат за излъчване на единица.

[правила Вградени за стандарт C99]

1. Функцията, в която всички си декларация (включително определения) са етикетирани инлайн и никога като ученик. Тя трябва да бъде определен в рамките на една единица превод (превод единица). Стандартът се отнася за този вариант, тъй като определение инлайн (определение вградено). Няма да има отделен обект код, генериран, така че това определение не може да бъде извикан от друга единица излъчване (от друг модул).

Можете да (2) да имат отделно (не инлайн) определение на същата функция в друга превод единица, компилаторът може да избира отделно определение или инлайн дефиниция.

Тези функции не могат да съдържат променливите статични променливи, и не могат да имат достъп до статичните определения или функции в друг източник файл (т. Е., не там, където инлайн функции са обявени).

В този пример, всички декларации и определения, използвани в текста, но не се използват ученик:

Тази функция не може да бъде извикан от други файлове; Вместо това, в друг файл трябва да има собствена дефиниция.

Забележка (2): в стандарта не е ясно описание на това. Той казва, че инлайн определяне не забранява извън (външна) дефиниция някъде другаде, но след това тя осигурява алтернатива на външни дефиниции. За съжаление, това не дава ясна представа - трябва да го действително съществува извън обхвата на определението. На практика, ако не е посочено да се измъчваш компилатора, а след това ще има следното правило: ако искате да запазите вградена функция е изцяло частна за една единица от превод, направете го определя като статичен инлайн.

2. Функция, където най-малко една декларация маркира като инлайн, но къде някои други декларации не споменават инлайн, или по-ученик. Определяне на функцията трябва да бъде в едно и също разпращане yunite такава декларация. отделен обектен код се генерира (например, за нормалната функция) и може да бъде извикан от други звена излъчват програмата си.

Тя се използва и да се ограничи статично определение, вече бе споменато по-горе.

В този пример, всички декларации и определения, използвани в текста, но един ученик добавя:

В този пример, една от декларациите, не се маркира като инлайн:

В нито един от тези два примера, функцията може да бъде извикан от други файлове.

3. Функцията се определя като статичен вградени. местното определение може да бъде издадена, ако е необходимо. Можете да имате няколко определения по програмата, излъчвани в различни мерни единици, и всички те ще работят като отделни функции. Просто се изхвърля инлайн намалява преносимостта на програми (отново, при равни други условия).

Това може да бъде полезно за малки функции, които иначе биха могли да бъдат определени като макроси. Ако функцията не винаги е вградена, а след това можете да получите дублира своя код с всички вече описаните по-горе проблеми.

Разумен подход би бил да се постави функция статично инлайн в заглавния файл, или ако трябва да се използва широко, или просто в кодови файлове източници, които използват тези функции - ако те се използват някога в този файл.

В този пример, функцията се определя като статичен вградени:

Първите два варианта са естествено, взети заедно. Или сте всички инлайн и ученик на едно място за автономна определение на заявката, или да пишете инлайн почти навсякъде, но се изключват, че е необходимо веднъж да получи самостоятелно определение.

Основната функция не може да се вгражда (инлайн) функция.

(C ++ по-строги правила. Функция, която се появи някъде като инлайн, всички трябва да се определи като вграден, а трябва да се определи по същия начин във всички звена на превода, където тя се използва)

[Пътека правила за GNU компилатор]

1. Функция определено инлайн сами. Винаги самогенерираният обектен код. Можете да напишете само едно определение като този за цялата програма. Ако искате да го използвате от други звена на превод, поставете декларацията в заглавната част на файла; но това няма да направи интеграция на модулите за излъчване, в които се използва заглавната си част.

Тази опция е от ограничена полза, ако искате да използвате функцията на един yunite превод, по-разумно е да го направи статичен инлайн, както е показано във вариант 3 - ако евентуално не би искал да има форма, която позволява функции да бъдат изградени в повече от една единица излъчване.

Въпреки това, тази опция е използването на инлайн ключова дума няма да имат предимство на програмата е сведена до преносим програма с една и съща стойност (ако не използвате всеки друг непреносимо дизайн).

2. функция, дефинирана като екстернант вградени. Самостоятелен обект код не се генерира всякога. Можете да имате няколко от тези определения, и вашата програма ще продължи да работи. Въпреки това вие също трябва да се добави някъде и не-инлайн определение, в случай, че някъде не функционират използва като инлайн.

Това дава достатъчно семантика (това е възможно да се избегне дублирането на функциите на обектен код), но малко по-неудобни за използване.

Един от начините да използвате тази опция - сложи определенията в заглавната част на файла, съраунд предпроцесорни оператор #if, които ще бъдат оценени, за да е вярно или когато използвате GNU C, или когато заглавието е свързан от файл, който съдържа определението, издадено (дали GNU C или не ). В последния случай EXTERN пропуснатото (например EXTERN запис, и се определя чрез # определят екстернант или като, или като свободен). #else клон ще съдържа декларация за функции за не-GNU компилатори.

3. функция, дефинирана като статичен вградени. Ако е необходимо, ще се генерира самостоятелно обектен код. Можете да имате няколко определения в програмата, излъчвани в различни мерни единици, и той ще работи. Това е същата версия на осъзнаването, че за правилата C99.

С освобождаването 4.3 GNU C компилатор поддържа правила C99 включване, както е описано по-горе, и да ги използва по подразбиране с опции -std = C99 или -std = gnu99. Старите правила могат да бъдат поискани в рамките на нова опция компилатор -gnu89-редови, или с помощта на gnu_inline функция атрибут.

Ако C99 са правилата, които определят GCC __GNUC_STDC_INLINE__ макроса. Започвайки с GCC 4.1.3 е макро __GNUC_GNU_INLINE__, ако се използва само правила ССЗ, но старите компилатори използват едни и същи правила, без да следва всяка макро. Можете да коригирате ситуация, като използва част от код по следния начин:

[стратегии за използване редово функции]

Следните правила се препоръчва да се възможните модели за работа инлайн функции, повече или по-малко, засягащи преносимост.

Например, в заглавната част на файла:

Можете да подкрепите наследените компилатори (например без вградени) през -Dinline = опция "," въпреки че това ще доведе до загуба на паметта, ако компилаторът не се оптимизира неизползваните функции.

GNU C. Модел Използвайте ученик инлайн в общия заглавния файл и да даде определението някъде във файла .c, по възможност с помощта на макро - за да се гарантира появата навсякъде от един и същи код. Например, в заглавната част на файла:

и да определи само един файл с изходен код:

C99 модел. Използвайте вградени в общия заглавния файл, и се дава дефиниция някъде във файла .c, чрез ученик на декларация. Например, в заглавния файл:

и само един на някои от изходния код на файла за:

За да добавите поддръжка за по-старите компилатори, ще трябва да платите всичко това код за предпроцесорни така че декларацията може да се разглежда в общия заглавната част, и решителност са ограничени до една бизнес единица на преводи, при които функцията е дефинирана чрез инлайн.

Комплекс модел пренасяне. Използвайте макро, за да изберете определението или използването ученик инлайн за GNU C, на място, за C99, или без нищо от това. Например, в заглавието:

и само един файл с изходен код:

Ние подкрепяме наследените компилатори имат същите проблеми, както с GNU В. модел

1. Вградени функции в C сайт: greenend.org.uk.
2. Inline функция е бърз като Macro сайт: gcc.gnu.org.
3. Възможности Контрол C ++ диалект сайт: gcc.gnu.org.