The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
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, 11:18 , 24-Окт-05 (1)
    При обработке потенциально возникшего исключения, экземпляр AB класса ab должен быть разрушен, поскольку ab имеет нетривиальный деструктор.
    Обработка исключений в компиляторе GCC 2.95 построена на setjmp/longjmp и требует сохранения контекста перед вызовом func.

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

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

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

        • gcc+exception+destructor=вздутие кода, !*! Vital, 17:04 , 24-Окт-05 (4)
          ужас..

          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 не могу использовать, т.к. в программе все таки исключения используются




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру