Объясните причину следующего явления.
есть код: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]
При обработке потенциально возникшего исключения, экземпляр AB класса ab должен быть разрушен, поскольку ab имеет нетривиальный деструктор.
Обработка исключений в компиляторе GCC 2.95 построена на setjmp/longjmp и требует сохранения контекста перед вызовом func.Варианты решения:
1. Объявить func как не кидающую исключения
2. Отключить EH вообще
3. Перейти на GCC >=3.2
ну в общем то я так и предполагал.
только функция func тут не причем, и без нее таже картинка, вставил, чтобы компилятор при оптимизации не слишком усердствовал.
Кстати, проверил на борландовском компиляторе, от древнего BC5.0 - таже картинка, а на gcc version 3.3.2 20031022 (Red Hat Linux 3.3.2-1) все красиво :)
Такой вопрос. Как сказать компилятору, что исключения не будут генерироваться, если компилятор не понимает слова nothrow (gcc 2.95)?
>Такой вопрос. Как сказать компилятору, что исключения не будут генерироваться, если компилятор
>не понимает слова nothrow (gcc 2.95)?Стандарт велит писать throw() и 2.95 должен это понимать. К сожалению не могу проверить - этой версии нет под рукой. Если не работает, то используй -fno-exceptions в коммандной строке чтобы отключить EH вообще.
ужас..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 не могу использовать, т.к. в программе все таки исключения используются