Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Inline функция в C++


Автор: Tulsky 5.2.2006, 22:06
Объясните пожалуйста что происходит с inline функцией на уровне машинных команд.

Автор: MAKCim 5.2.2006, 22:13
я так полагаю, код функции генерируется в месте ее вызова
Код

<команды>
код функции
<команды>

Автор: Partizan 5.2.2006, 22:16
а? что значит на уровне машинных команд?

inline означает то, что в программе при компиляции вместо вызовов функции будет вставлен её код(скорее всего)...inline говорит компилятору сгенерить код функции в месте её вызова...
то есть если мы inline функцию вызвали 4 раза то в 4 местах вставится код этой функции...
за счёт этого увеличивается размер прогшраммы и её производительность...

но в основном компиляторы игнорируют inline в объявлении функций, за исключением самых малых...

Автор: BreakPointMAN 6.2.2006, 02:19
О'кей, рассмотрим на простом примере. C++ Builder 6, Console Application, Release-версия.
Код
#include <conio.h>
#include <stdio.h>

int sum(int x, int y)
   {
    return x+y;
   }

int main(int argc, char* argv[])
   {
    int x,y,z;
    printf("Enter x, y: ");
    scanf("%d,%d", &x, &y);
    printf("sum of %d and %d is %d", x, y, sum(x,y));
    getch();
    return 0;
   }


...и-и-и во что это превратилось:

Функция main:
Код
.text:00401228 ; --------------- S U B R O U T I N E ---------------------------------------
.text:00401228
.text:00401228 ; Attributes: bp-based frame
.text:00401228
.text:00401228 ; int __cdecl main(int argc,const char **argv,const char *envp)
.text:00401228 _main           proc near               ; DATA XREF: .data:0040E04Co
.text:00401228
.text:00401228 var_8           = dword ptr -8
.text:00401228 var_4           = dword ptr -4
.text:00401228 argc            = dword ptr  8
.text:00401228 argv            = dword ptr  0Ch
.text:00401228 envp            = dword ptr  10h
.text:00401228
.text:00401228                 push    ebp
.text:00401229                 mov     ebp, esp
.text:0040122B                 add     esp, 0FFFFFFF8h
.text:0040122E                 push    offset format   ; "Enter x, y: "
.text:00401233                 call    _printf
.text:00401238                 pop     ecx
.text:00401239                 lea     eax, [ebp+var_8]
.text:0040123C                 push    eax
.text:0040123D                 lea     edx, [ebp+var_4]
.text:00401240                 push    edx
.text:00401241                 push    offset aDD      ; "%d,%d"
.text:00401246                 call    _scanf
.text:0040124B                 add     esp, 0Ch
.text:0040124E                 mov     ecx, [ebp+var_8]
.text:00401251                 push    ecx
.text:00401252                 mov     eax, [ebp+var_4]
.text:00401255                 push    eax
.text:00401256                 call    sub_40121C
.text:0040125B                 add     esp, 8
.text:0040125E                 push    eax
.text:0040125F                 mov     edx, [ebp+var_8]
.text:00401262                 push    edx
.text:00401263                 mov     ecx, [ebp+var_4]
.text:00401266                 push    ecx
.text:00401267                 push    offset aSumOfDAndDIsD ; "sum of %d and %d is %d"
.text:0040126C                 call    _printf
.text:00401271                 add     esp, 10h
.text:00401274                 call    _getch
.text:00401279                 xor     eax, eax
.text:0040127B                 pop     ecx
.text:0040127C                 pop     ecx
.text:0040127D                 pop     ebp
.text:0040127E                 retn
.text:0040127E _main           endp
.text:0040127E
.text:0040127E ; ---------------------------------------------------------------------------


Функция sum:
Код
.text:0040121C ; --------------- S U B R O U T I N E ---------------------------------------
.text:0040121C
.text:0040121C ; Attributes: bp-based frame
.text:0040121C
.text:0040121C sub_40121C      proc near               ; CODE XREF: _main+2Ep
.text:0040121C
.text:0040121C arg_0           = dword ptr  8
.text:0040121C arg_4           = dword ptr  0Ch
.text:0040121C
.text:0040121C                 push    ebp
.text:0040121D                 mov     ebp, esp
.text:0040121F                 mov     eax, [ebp+arg_0]
.text:00401222                 add     eax, [ebp+arg_4]
.text:00401225                 pop     ebp
.text:00401226                 retn
.text:00401226 sub_40121C      endp
.text:00401226
.text:00401226 ; ---------------------------------------------------------------------------


Если бы функция sum была inline, то мы получили бы следующее:
Код
.text:0040121C ; --------------- S U B R O U T I N E ---------------------------------------
.text:0040121C
.text:0040121C ; Attributes: bp-based frame
.text:0040121C
.text:0040121C ; int __cdecl main(int argc,const char **argv,const char *envp)
.text:0040121C _main           proc near               ; DATA XREF: .data:0040E04Co
.text:0040121C
.text:0040121C var_8           = dword ptr -8
.text:0040121C var_4           = dword ptr -4
.text:0040121C argc            = dword ptr  8
.text:0040121C argv            = dword ptr  0Ch
.text:0040121C envp            = dword ptr  10h
.text:0040121C
.text:0040121C                 push    ebp
.text:0040121D                 mov     ebp, esp
.text:0040121F                 add     esp, 0FFFFFFF8h
.text:00401222                 push    offset format   ; "Enter x, y: "
.text:00401227                 call    _printf
.text:0040122C                 pop     ecx
.text:0040122D                 lea     eax, [ebp+var_8]
.text:00401230                 push    eax
.text:00401231                 lea     edx, [ebp+var_4]
.text:00401234                 push    edx
.text:00401235                 push    offset aDD      ; "%d,%d"
.text:0040123A                 call    _scanf
.text:0040123F                 add     esp, 0Ch
.text:00401242                 mov     ecx, [ebp+var_4]
.text:00401245                 add     ecx, [ebp+var_8]
.text:00401248                 push    ecx
.text:00401249                 mov     eax, [ebp+var_8]
.text:0040124C                 push    eax
.text:0040124D                 mov     edx, [ebp+var_4]
.text:00401250                 push    edx
.text:00401251                 push    offset aSumOfDAndDIsD ; "sum of %d and %d is %d"
.text:00401256                 call    _printf
.text:0040125B                 add     esp, 10h
.text:0040125E                 call    _getch
.text:00401263                 xor     eax, eax
.text:00401265                 pop     ecx
.text:00401266                 pop     ecx
.text:00401267                 pop     ebp
.text:00401268                 retn
.text:00401268 _main           endp
.text:00401268
.text:00401268 ; ---------------------------------------------------------------------------


Как видно, во втором случае sum не оформлена в виде отдельной функции, а "встроена" в main... smile

Автор: Fin 6.2.2006, 03:14
Стоить добавить только, что inline функции компилятор отрабатывает только в релиз режиме. В Дебаг режиме, он игнорирует слово inline.

Автор: Tulsky 6.2.2006, 06:43
А книжку про все эти дела некто не подскажет?

Автор: _hunter 6.2.2006, 11:50
любая книжка по асму ( не справочник )
потом любая старая книжка по С ( не С++ )

Автор: BreakPointMAN 6.2.2006, 11:57
"Фундаментальные основы хакерства. Искусство дизассемблирования." © Крис Касперски - в книге есть раздел "Идентификация встраиваемых (inline) функций". Но не думаю, что тебе это много даст. Еще можешь на форум http://wasm.ru/forum заглянуть. Кажется, я там недавно видел вопрос по автоматическому поиску inline-функций в коде, может для себя что полезное найдешь...

Автор: Tulsky 7.2.2006, 10:08
Цитата

любая книжка по асму ( не справочник )
потом любая старая книжка по С ( не С++ )


Не уверен, что в C был inline, но всё же какую книгу по окнкретней вы можете посоветовать?

Автор: _hunter 7.2.2006, 11:18
были. как же без них:
http://www.greenend.org.uk/rjk/2003/03/inline.html ( в качестве примера )
а насчет книги... я ж говорю -- любая из старых ( до 90-х ) вполне подойдет ( ели это именно книга, а не брошурка страниц на 200 )

Автор: Helicopterr 7.2.2006, 23:37
При трансляции исходного кода в машинный имена ф-ций заменяются их адресами. ОС руководит указателями на эти адреса. В случае использования спецификатора inline пред вызовом функции указатель не создаётся. И, как уже было сказано, в месте вызова оказывается ее код. Для чего это надо? Если inline ф-ция мала, то будет быстрее работать программа.

Автор: AlexPro 8.2.2006, 12:41
Tulsky, а что, собственно, вы хотите найти в книге? В тех книгах, что мне пришлось прочесть, inline-функциям было посвящено не более двух-трех строк. И этой информации, в принципе, достаточно. BreakPointMAN на примере хорошо продемонстрировал суть inline-функций. Единственно, что можно добавить, что inline является лишь рекомендацией компилятору. Если в программе есть очень короткие (скажем 1-5 команд) функции, которые используются очень часто (и особенно в циклах), объявление их inline может дать существенный прирост производительности за счет исключения накладных расходов при вызове функции. Побочный эффект - некоторое увеличение размера программы.

Автор: Tulsky 8.2.2006, 21:40
Цитата

Tulsky, а что, собственно, вы хотите найти в книге?

Мне интересен процесс на уровне машинных команд, т.е. уровне стеков, конвееров и регистров.
Помогите, объясните, уж больно надо, иль хоть книгу посоветуёте стоющую.

Автор: BreakPointMAN 8.2.2006, 22:19
Tulsky, а ты хотя бы приблизительное представление об этих "стеках, конвеерах и регистрах" имеешь? Что-то мне подсказывает, что не имеешь... Вообще говоря, из моего сообщения от 6.2.2006, 02:19 ты уже мог бы извлечь некоторое кол-во полезной для тебя информации, но, судя по всему, ты хочешь, чтобы тебе все разжевали и поднесли на блюдечке. Не будет такого. Бери книги по ассемблеру, по си, и внимательно, вдумчиво читай.

Автор: Tulsky 9.2.2006, 09:40
Цитата

Бери книги по ассемблеру, по си, и внимательно, вдумчиво читай.

Читаю! Но книжка размером 500 станиц, а информация нужна как можно скорее.

Автор: AlexPro 9.2.2006, 10:58
Tulsky, сдается мне, в этом топике про inline функции написано уже больше, чем в любой книге. Здесь тебе и теоретические обоснования, и практический пример. Какая еще нужна информация? Если это не то что нужно - точнее сформулируй свой вопрос.

Автор: _hunter 9.2.2006, 11:32
Tulsky, на уровне машинных комманд inline-функция реализована просто набором команд этой функции. все.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)