Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
[C++] /ЕHa или /EHsc 23.04.07 07:31 Число просмотров: 2645
Автор: void <Grebnev Valery> Статус: Elderman Отредактировано 23.04.07 07:35 Количество правок: 1
|
Вопрос о "накладных расходах" при включении в код __try/__except и компиляции с /ЕHa или /EHsc. "Накладные расходы" по размеру приложения и, что самое главное, по скорости желательно получить маленькие. Пример кода, некоторая статистика и выводы приведены ниже. Поделитесь, пожалуйста, опытом.
Надо "обернуть" имеющееся API (например, API MySQL, разработаное на С) в C++. Обёртки будут использоватьcя в приложениях VC++6.0/8.0 3-х типов: STL; STL+MFC; MFC.
Исключительные ситуации, увы, не обрабатываются API :(
Для этого сделан класс:
class CMySqlException : public std::exception который throw CMySqlException(param) в вызывающий код.
Например:
class CMySqlDataReader
{
...
public:
bool Read()
{
TRY_SEH
m_curr_row = mysql_fetch_row(m_result);
ON_CATCH_SEH ( throw CMySqlException (m_handle);)
return (m_curr_row != NULL);
}
...
};
Здесь
mysql_fetch_row - одна из функций API, которая может "анормал терминайте программ", если не обработать еxception (например, m_result == NULL или содержит мусор)
TRY_SEH\ON_CATCH_SEH определены следующим образом:
#defineSEH #ifdefSEH #define TRY_SEH __try {
#define ON_CATCH_SEH(_expressions) } __except(EXCEPTION_EXECUTE_HANDLER) { _expressions; }
#else
#define TRY_SEH ((void)0);
#define ON_CATCH_SEH(ex) ((void)0);
#endif
Тестировалось простейшее приложение MySQL (локально), скомпилированное в 4-версиях:
1) /EHsc и //#defineSEH(__try/__except не использовалось)
2) /EHsc и #defineSEH(__try/__except использовалось)
3) /EHа и //#defineSEH(__try/__except не использовалось)
4) /EHа и #defineSEH(__try/__except использовалось)
Тестирование показало:
1) Не обнаружено сколь-нибудь заметной разницы в скорости выполнения кода для всех 4-х вариантов. Это можно обьяснить тем, что ботлнэк в данном примере - это обращение к базе данных (хоть бы и локально). По идее же, включение /EHа или __try/__except должно было б замедлить программу. Причём, /EHа должно бы оказывать глобальное и более ошутимое влияние.
2)Размер "релиза" оказался: 16Кбт (1), 32Кбт (2,3), 19Кбт (4). Это трудно обьяснить, когда для /EHa явное включение в код __try/__except привело к уменьшению размера кода, а не увеличению. Разве, что компилятор так оптимизирует код.
3) Вопреки ожиданиям, /EHa без явного __try/__except (3), всёже "пропускает" некоротые exceptions, не перенаправляя их в C++ try/catch(std::exception& error).
Однако, как и обещано Microsoft, эти exceptions ловятся в catch(...). От этого может немного усложнится обработка (re-throw) в проложениях MFC.
4) И /EHa, и /EHsc в сочетании с __try/__except (2,4) всегда перенаправляют exceptions в C++ try/catch(std::exception& error) как и в catch(CMySqlException &ех). Это хорошо для приложений MFC.
Выводы:
1) Обязательно использовать __try/__except в критичных учацтках кода вне зависимости используется /EHa, или нет. Иначе /EHa может перенаправлять exception в catch(...) вместо catch(CMySqlException &ех) и вместо catch(std::exception& error). Это может быть критично для приложений MFC, где обработка виполняетя в коде типа:
TRY{...}
CATCH_ALL(e) {
CMySqlException dbe;
if ( e->IsKindOf(RUNTIME_CLASS(CMySqlException ) ))
{
CMySqlException *pAfxDbex = (CMySqlException *) e;
...
}
else
{
...
}
AfxThrowLastCleanup();
throw dbe;
}
END_CATCH_ALL
2) Заманчиво использование /EHa. Поскольку в сочетании с явным включением __try/__except на критических участках кода, это только придаст большую надежность коду:
- пропущеные программистом "С" SHE все равно будут в catch(...)
- не пропущеные в __try/__except "С" SHE будут re-throw и "попадутся" в catch(CMySqlException &ех) или catch(std::exception& error) в вызывающем коде.
Сомнения здесь относительно приложений MFC. Я не проводил теститования приложений MFC, скомпилированных с /EHa. Кроме того, поскольку /EHa оказывает глобальное влияние на весь проект, то не ясно какие оверхеды могут возникнуть.
Короче простой вопрос: кто как делает, когда приложение представляет смесь
API "C", STL, MFC?
Спасибо.
|
- [C++] /ЕHa или /EHsc - void 23.04.07 07:31 [2645]
|
|
|