anonymous@RULINUX.NET~# Last login: 2024-11-05 10:52:22
Регистрация Вход Новости | Разметка | Пользователи | Галерея | Форум | Статьи | Неподтвержденное | Трекер | Правила форума | F.A.Q. | Ссылки | Поиск
[#] [Добавить метку] [Редактировать]
Скрыть

c++ final class почему компилятор не делает inline

cpp

        struct A
        {
            virtual long fun(long a)
            {
                return a+11;
            }
        };
        struct A2
        {
            virtual long fun2(long a)
            {
                return a+44;
            }
        };
        struct C: public A
        {
            long fun(long a) final
            {
                return a+33;
            }
        };
         
        struct D final: public A2
        {
        };
         
         
        long gmain(long j, C &c, D &d)
        {
            j = c.fun(j);   // direct   j = j1 + 33
            j*=141;         // 45 * (j1+33) * 141 = j1*141 + 4653
            j = d.fun2(j);  // direct?  j = j1*141 + 4697
            j*=151;         // == j1*21291 + 709247
            return j;
        }

 


результат (gcc 5.3.0), /opt/gdc/bin/g++ -std=c++11 -O3 -S virt-cpp-inline.cpp

asm


    .globl  _Z5gmainlR1CR1D
    .type   _Z5gmainlR1CR1D, @function
_Z5gmainlR1CR1D:
.LFB3:
    .cfi_startproc
    leaq    33(%rdi), %rax               << inline
    imulq   $141, %rax, %rsi
    movq    (%rdx), %rax
    movq    (%rax), %rax
    cmpq    $_ZN2A24fun2El, %rax
    jne .L3                                      << virtual inline ?
    leaq    44(%rsi), %rax
    imulq   $151, %rax, %rax
    ret
    .p2align 4,,10
    .p2align 3
.L3:
    subq    $8, %rsp
    .cfi_def_cfa_offset 16
    movq    %rdx, %rdi
    call    *%rax
    addq    $8, %rsp
    .cfi_def_cfa_offset 8
    imulq   $151, %rax, %rax
    ret
    .cfi_endproc
 

anonymous(*) (2016-03-18 14:06:48)

Opera/9.80 (X11; Linux x86_64) Presto/2.12.388 Version/12.16

[Ответить на это сообщение]
[#] [Добавить метку] [Редактировать] Ответ на: c++ final class почему компилятор не делает inline от anonymous 2016-03-18 14:06:48
avatar
Скрыть

Re: c++ final class почему компилятор не делает inline



один вызов развернул, второй вообще оставил виртуальным.

Это баг или я чего-то не понимаю в final ?

anonymous(*)(2016-03-18 14:08:55)

Opera/9.80 (X11; Linux x86_64) Presto/2.12.388 Version/12.16
avatar
Скрыть

Re: c++ final class почему компилятор не делает inline

Мне кажется это всё от того, что метод объявлен виртуальным. c.fun не объявлен виртуальным, а A2::fun2 же объявлен. И, КМК, final запрещает наследовать класс, но с чего бы ему развиртуализировать метод?

anonymous(*)(2016-03-18 23:08:29)

avatar
Скрыть

Re: c++ final class почему компилятор не делает inline

оба метода являются виртуальными и оба допускают девиртуализацию и инлайнинг метод C::fun виртуальный, т.к. является таковым в базовом классе A. слово virtual не обязательно писать для метода C::fun.

вызов c.fun() можно встроить, т.к. даже если по факту объект c является неким типом C1, который унаследован от C, то метод fun не может быть переопределен в C1, т.к. помечен словом final

вызов d.fun2() можно встроить, т.к. переменная d не может являться неким типом D1, унаследованным от D, т.к. класс D помечен словом final то есть в статике (при компиляции) мы заранее знаем, какие именно методы должны вызваться и можем их встроить. хаки в таблицах виртуальных функций уже идут лесом, т.к. это UB

anonymous(*)(2016-03-19 20:15:08)

Opera/9.80 (X11; Linux x86_64) Presto/2.12.388 Version/12.16
avatar
Скрыть

Re: c++ final class почему компилятор не делает inline

> мы заранее знаем, какие именно методы должны вызваться

Где-нибудь у класс D появляется "сосед" E:

cpp

        struct E final: public A2
        {
            virtual long fun2(long a)
            {
                return a+144;
            }
         };
 

И код, которому абстрактно на конкретную реализацию:
cpp

long theUniversalFunMultiplier(A2 &a2, long p)
{
    return 2 * a2.fun2(p);
}
 

anonymous(*)(2016-03-20 12:50:01)
Отредактировано anonymous по причине "не указана"
Mozilla/5.0 (X11; Fedora; Linux x86_64; rv:45.0) Gecko/20100101 Firefox/45.0
avatar
Скрыть

Re: c++ final class почему компилятор не делает inline

В функции gmain (о которой изначально шла речь) - заранее известно, какие конкретные методы будут вызваны. Тело функции gmain можно целиком inline-ить.0

В функции theUniversalFunMultiplier - заранее неизвестно, какие методы будут вызваны. Тело theUniversalFunMultiplier нельзя целиком inline-ить.

anonymous(*)(2016-03-21 08:41:20)

Opera/9.80 (X11; Linux x86_64) Presto/2.12.388 Version/12.16
avatar
Скрыть

Re: c++ final class почему компилятор не делает inline

Я к тому, что слово "final" тут скорее всего не играет роли.

anonymous(*)(2016-03-21 17:54:04)

Mozilla/5.0 (X11; Fedora; Linux i686; rv:42.0) Gecko/20100101 Firefox/42.0
[#] [Добавить метку] [Редактировать] Ответ на: c++ final class почему компилятор не делает inline от anonymous 2016-03-18 14:06:48
avatar
Скрыть

Re: c++ final class почему компилятор не делает inline

погодите, народ!

Инлайнинг — это не свойство вызываемой функции, а свойство контекста, из которого вызвана функция. Разные вызовы одной и той же функции могут как заинлайниться, так и нет.

Тот факт, что некоторые вызовы были заинланйнены, не отменяет генерации отдельного символа для заинлайненной функции и не модифицирует vtable. Это позволяет использовать обычный vtable/call там, где инлайнинг невозможен, например, в преведенной выше theUniversalFunMultiplier.

anonymous(*)(2016-03-23 00:11:42)

Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.21 (KHTML, like Gecko) konqueror/4.14.17 Safari/537.21
avatar
Скрыть

Re: c++ final class почему компилятор не делает inline

ТС-то интересуется почему компилятор не заинлайнил оба метода в конкретной ситуации. Вроде уже договорились, что final тут ни при чём, но по сути вопроса пока идей чота нет.

anonymous(*)(2016-03-23 15:39:40)

Этот тред читают 2 пользователя:
Анонимных: 2
Зарегистрированных: 0




(c) 2010-2020 LOR-NG Developers Group
Powered by TimeMachine

Valid HTML 4.01 Transitional Правильный CSS!