URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 4758
[ Назад ]

Исходное сообщение
"gcc+exception+destructor=вздутие кода"

Отправлено Vital , 24-Окт-05 04:33 
Объясните причину следующего явления.
есть код:

struct  ab {
        int     a;
        int     b;

        ab () : a(1), b(2) {}
        ~ab () {}
};

void func ( ab& ){
}

void main () {
        ab AB;
        func (AB);
}

После компиляции получаем код функции main:

main:
        pushl %ebp
        movl %esp,%ebp
        subl $36,%esp
        pushl %ebx
        call __get_eh_context
        movl %eax,%ebx
        movl $1,-8(%ebp)
        movl $2,-4(%ebp)
        movl 4(%ebx),%edx
        movl 4(%edx),%eax
        movl %eax,-20(%ebp)
        movl $_$_2ab,-16(%ebp)
        leal -8(%ebp),%eax
        movl %eax,-12(%ebp)
        leal -20(%ebp),%ecx
        movl %ecx,4(%edx)
        addl $-12,%esp
        pushl %eax
        call func__FR2ab
        movl 4(%ebx),%edx
        movl 4(%edx),%eax
        movl (%eax),%eax
        movl %eax,4(%edx)
        xorl %eax,%eax
        movl -40(%ebp),%ebx
        leave
        ret

Если закомментировать деструктор, получим ожидаемый компактный код:

main:
        pushl %ebp
        movl %esp,%ebp
        subl $24,%esp
        leal -8(%ebp),%eax
        movl $1,-8(%ebp)
        movl $2,4(%eax)
        addl $-12,%esp
        pushl %eax
        call func__FR2ab
        xorl %eax,%eax
        leave
        ret

Почему компилятор так делает и можно ли от этого вылечиться?
Использовался компилятор gcc version 2.95.4 20020320 [FreeBSD]


Содержание

Сообщения в этом обсуждении
"gcc+exception+destructor=вздутие кода"
Отправлено gigaza , 24-Окт-05 11:18 
При обработке потенциально возникшего исключения, экземпляр AB класса ab должен быть разрушен, поскольку ab имеет нетривиальный деструктор.
Обработка исключений в компиляторе GCC 2.95 построена на setjmp/longjmp и требует сохранения контекста перед вызовом func.

Варианты решения:
    1. Объявить func как не кидающую исключения
    2. Отключить EH вообще
    3. Перейти на GCC >=3.2


"gcc+exception+destructor=вздутие кода"
Отправлено Vital , 24-Окт-05 13:10 
ну в общем то я так и предполагал.
только функция func тут не причем, и без нее таже картинка, вставил, чтобы компилятор при оптимизации не слишком усердствовал.
Кстати, проверил на борландовском компиляторе, от древнего BC5.0 - таже картинка, а на gcc version 3.3.2 20031022 (Red Hat Linux 3.3.2-1) все красиво :)
Такой вопрос. Как сказать компилятору, что исключения не будут генерироваться, если компилятор не понимает слова nothrow (gcc 2.95)?

"gcc+exception+destructor=вздутие кода"
Отправлено gigaza , 24-Окт-05 15:33 
>Такой вопрос. Как сказать компилятору, что исключения не будут генерироваться, если компилятор
>не понимает слова nothrow (gcc 2.95)?

Стандарт велит писать throw() и 2.95 должен это понимать. К сожалению не могу проверить - этой версии нет под рукой. Если не работает, то используй -fno-exceptions в коммандной строке чтобы отключить EH вообще.


"gcc+exception+destructor=вздутие кода"
Отправлено Vital , 24-Окт-05 17:04 
ужас..

struct  ab {
        int     a;
        int     b;

        ab () throw() : a(1), b(2) {}
        ~ab () throw () {}
};

void func ( ab& ) throw () {
}

void main () {
        ab AB;
        func (AB);
}

код становится еще больше...

fno-exceptions не могу использовать, т.к. в программе все таки исключения используются