Мобильная версия форумов
Открыть
 −2°C
завтра: −11°C
Погода в Перми
−2°C
утром−3°C
днем−6°C
завтра−11°C
Подробно
 65,51
−0.0252
Курс USD ЦБ РФна 23 февраля
65,5149
−0.0252
 74,33
+0.0369
Курс EUR ЦБ РФна 23 февраля
74,3332
+0.0369
  • experienced

    Сообщений: 831

    язык c++
    Как известно если компилятор по каким бы то ни было причинам не может сделать функцию(определённую как inline) встраиваемой, он делает из неё обычную. Как узнать, что inline функция оттранслировалась действительно как встраиваемая? Ну и в догонку, можноли определять перегружаемые встроенные функции?
    Заранее спасибо за ответы.

  • veteran

    Сообщений: 1583

    Перегрузка определяетяся на этапе компиляции, так что по идее должно быть можно перегруженные функции делать inline

    Насчет того как узнать, можно например дебаггером посмотреть

  • experienced

    Сообщений: 831

    В ответ на: Насчет того как узнать, можно например дебаггером посмотреть
    А как дебагером смотреть? По f11 в неё заходит так же, как в обыкновенную.

  • veteran

    Сообщений: 1583

    Ассемблерный листинг посмотри, там call есть или нет

  • experienced

    Сообщений: 831

    004020F3 call @ILT+55(ddfgg) (0040103c)
    функция ddfgg причём call есть в любом случае, хотя примерчик книжный, сорри если туплю, просто с ассемблером туго у меня...

  • veteran

    Сообщений: 1583

    значит нифига не inline

  • experienced

    Сообщений: 831

    ok.
    листинг
    В ответ на: // nevill.cpp : Defines the entry point for the console application.
    //
    #include <iostream.h>

    //using namespace std;


    inline int even(int a){

    return ! (a%2);

    }



    int main()
    {
    if(even(10)) cout << "true" <<endl;else cout << "false" <<endl;

    return 0;
    }
    Disassembly

    В ответ на: 0040106A call @ILT+20(even) (00401019)
    0040106F add esp,4
    00401072 test eax,eax
    00401074 je main+43h (00401093)
    00401076 push offset @ILT+10(endl) (0040100f)
    0040107B push offset string "true" (00425024)
    00401080 mov ecx,offset cout (004289c0)
    00401085 call ostream::operator<< (00401470)
    0040108A mov ecx,eax
    0040108C call @ILT+0(ostream::operator<<) (00401005)
    00401091 jmp main+5Eh (004010ae)
    00401093 push offset @ILT+10(endl) (0040100f)
    00401098 push offset string "false" (0042501c)
    0040109D mov ecx,offset cout (004289c0)
    004010A2 call ostream::operator<< (00401470)
    004010A7 mov ecx,eax
    004010A9 call @ILT+0(ostream::operator<<) (00401005)
    19:
    20: return 0;
    004010AE xor eax,eax
    21: }
    004010B0 pop edi
    004010B1 pop esi
    004010B2 pop ebx
    004010B3 add esp,40h
    004010B6 cmp ebp,esp
    004010B8 call __chkesp (00403550)
    004010BD mov esp,ebp
    004010BF pop ebp
    004010C0 ret
    здесь она точняк должна быть inline

  • veteran

    Сообщений: 1583

    Лень смотреть. Цель мучений какова?

  • experienced

    Сообщений: 831

    3D конечно-разностная аппроксимация...
    Очень сильно влияет на быстродействие...

  • veteran

    Сообщений: 1583

    да брось, лишняя пара call/ret ничего тебе не даст. оптимизировать надо алгоритмику, а не такие ньюасны реализации как inline

  • experienced

    Сообщений: 831

    :хехе:Ага 1000х1000х1000 сетка в каждой точке вычисляются 30 переменных, при вычислении каждой(порядка 20 000 раз - время) вызываются функции, это не пара call/ret,
    с алгоритмом то всё как раз понятно.

  • veteran

    Сообщений: 1583

    вызов функции дает оверхеад на одну пару call/ret. inline ничего не даст

  • experienced

    Сообщений: 831

    Какая разница, всё равно каждый раз запускается механизм вызова ф-ции и возврата значения, а не подстановка на этапе компиляции, лана спорить не буду, если лень переборю, запущу тестик с многократным вызовом обычных и инлайн и время замерю, рез-ты выложу.

  • activist

    Сообщений: 237

    Так компилер должен выдавать соответствующий ворнинг. Например Борланд выдает примерно такое:
    Warning 8026. такая растакая фанкшен are not expanded inline.
    Может у тебя это предупреждение отключено?

    Депрессия – это когда включаешь Интернет и не знаешь, куда пойти.

  • guru

    Сообщений: 5269

    &gt; Ну и в догонку, можноли определять перегружаемые встроенные функции?

    Можно. Но опять-таки, если компилятор "не сможет", то сделает из нее обычную.

    Вот (на английском):
    http://msdn2.microsoft.com/en-us/magazine/cc301407.aspx

  • veteran

    Сообщений: 1329

    В приведенном листенге она точно не inline.
    Хотя с точки зрения кода такая функция может быть inline - следовательно смотри настройки компилятора - там обязательно есть флажок типа такого Disable Inline Expansions или disable inline in debug или что-то подобное.
    Оптимизацией всетаки стоит начинать заниматся тогда, когда вы точно замерили где ваша программа тратит много времени - для этого есть соответствующие инструменты.
    Обычно 5% кода выполняются 95% времени и только для этих двух процентов имеет смысл делать оптимизацию. Вашу функцию лучше переписать так ! (a&amp;1) если компилятор этого за вас не сделал!

  • experienced

    Сообщений: 831

    Пример из книжки, поэтому должна быть inline. Почему Вы думаете что ф-ция из листинга не может быть инлайн? Пользую VS 6.0 поставил самый высокий уровень варнингов, ничего насчёт инлайн дебагер не выдаёт. Вообще всегда думал, что встраиваемая функция не сильно отличается от обыкновенной, кроме того что не должна содержать запрещённых конструкций(static var,switch,for,e.t.c.), зависит от компилятора.

  • guru

    Сообщений: 5269

    > 0040106A call @ILT+20(even) (00401019)

    Это не inline. Хотя по коду нет никаких препятствий для этого.
    Нужно копать VS 6.0

  • experienced

    Сообщений: 831

    Вот нарыл
    В ответ на: Microsoft Specific

    The __inline keyword is equivalent to inline.

    Even with __forceinline, the compiler cannot inline code in all circumstances. The compiler cannot inline a function if:

    The function or its caller is compiled with /Ob0 (the default option for debug builds).
    The function and the caller use different types of exception handling (C++ exception handling in one, structured exception handling in the other).
    The function has a variable argument list.
    The function uses inline assembly, unless compiled with /Og, /Ox, /O1, or /O2.
    The function returns an unwindable object by value, when compiled with /GX, /EHs, or /EHa.
    The function receives an unwindable copy-constructed object passed by value, when compiled with /GX, /EHs,, or /EHa.
    The function is recursive and not accompanied by #pragma inline_recursion(on). With the pragma, recursive functions can be inlined to a default depth of eight calls. To change the inlining depth, use inline_depth pragma.
    The function is virtual and is called virtually. Direct calls to virtual functions can be inlined.
    The program takes the address of the function and the call is made via the pointer to the function. Direct calls to functions that have had their address taken can be inlined.
    The function is also marked with the naked __declspec modifier.
    If the compiler cannot inline a function declared with __forceinline, it generates a level 1 warning (4714).

    Recursive functions can be substituted inline to a depth specified by the inline_depth pragma. After that depth, recursive function calls are treated as calls to an instance of the function. The inline_recursion pragma controls the inline expansion of a function currently under expansion. See the Inline-Function Expansion (/Ob) compiler option for related information.

    END Microsoft Specific
    Таким образом получается, что в отладочном режиме фиг добьёшься чтобы функция встраивалась. Интересно а как понять что в релизе всё успешно скомпилилось...

  • veteran

    Сообщений: 1329

    Именно это я и имел в виду, твоя inline функция исключена благодаря компиляции в режиме отладчика. Однако получить из Release build отладочную инфу тоже можно, поищи опции - нужно разрешить генерацию debug symbols (Programm database) и в линковке флажок поставить. Тогда твоя функция будет определенно inline. Можно кстати еще и ассемблерный код в студии получить - все тамже в опциях поройся.
    Только учти локальные переменные могут так извратится компилятором, что довольно сложно потом по ним судить что-то, но в принципе свою функцию найдешь я думаю

  • activist

    Сообщений: 109

    На последнего...

    Есть еще один вариант, правда, совсем не в стиле С++, но все же, может, окажется уместным:

    #define _EVEN_(a) (!((a) % 2))

    Исправлено пользователем wowik_2 (08.04.08 09:58)

Записей на странице:

Перейти в форум

Модератор: