C++-исключения vs SEH-исключения [re: Что можно.. ]

karkar

 
Про исключения ключевые слова Structured Exception Handling (SEH). В C++ в винде try/catch один хер через них работает, не думаю, что в .NET что-то принципиально другое.

Шол бы ты MSDN читать, прежде чем людей в заблуждение вводить.
 
Unlike the Win32 structured exception handling mechanism, the language itself provides support for C++ exception handling. These articles describe the Microsoft implementation of C++ exception handling, which is based on the ANSI C++ Standard.
For C++ programs, you should use C++ exception handling rather than structured exception handling.
Windows supplies its own exception mechanism, called SEH. It is not recommended for C++ or MFC programming.
  

try/catch - C++ exception. __try/__catch - SEH. Они разные и плохо совместимые. Без специальных телодвижений обычный catch SEH-исключения не ловит.

Serab

Шол бы ты MSDN читать, прежде чем людей в заблуждение вводить.
Попробуй просто написать программу, кинуть исключение throw и перехватить __except. Потом пиши сюда. Одно дело читать, другое — писать :smirk:
Примерно так:
void f
{
__try
{
throw 777;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
cout << "DeemOn sucks" << endl;
}
}

int main
{
try
{
f;
} catch (...)
{
cout << " sucks" << endl;
}
return 0;
}

В функцию вынес, потому что в пределах одной функции перемешивать нельзя.
try/catch - C++ exception. __try/__catch - SEH. Они разные и плохо совместимые.
Понимаю, ты только проснулся, тебе это пригрезилось =)
Без специальных телодвижений обычный catch SEH-исключения не ловит.
Это утверждение ортогонально тому, что в винде try/catch реализован через SEH, это следствие различия интерфейсов. Причем это не фундаментальное ограничение, ты сам пишешь, что оно обходится. Как? Можно почитать Рихтера, например.
upd: И если я сейчас правильно вспомню, то чтобы отловить SEH catch'ем, надо просто включить в компиляторе ключ. «Специальные телодвижения» нужны чтобы отличать SEH-исключениях от C++-ных.

karkar

Попробуй просто написать программу, кинуть исключение throw и перехватить __except. Потом пиши сюда. Одно дело читать, другое — писать :smirk:

ОК, беру твою прогу и выношу throw в другую функцию.
void t
{
throw 666;
}

void f
{
__try
{
t;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
cout << "DeemOn sucks" << endl;
}
}

Выводит " sucks".
сам пишешь, что оно обходится. Как? Можно почитать Рихтера, например.

А можно MSDN. ;) (_set_se_translator )

Serab

Ты лукавишь, у меня в новом проекте с настройками по умолчанию в студии 2008 __except правильно определяет кто на подсосе даже в том примере, какой приводишь ты.
Сказать-то что хочешь? Я вообще выношу cout << " sucks a buck of dicks" << endl; в функцию main. Твои действия?

karkar

Сказать-то что хочешь?
Что твои слова пока необоснованны. Один загадочный пример не годится, нужны ссылки на описание того, как действительно реализовано.
Тем более, что ты лукавишь

Нет, просто запускал в VC6. Настроек компилятора не трогал.

Dasar

Сказать-то что хочешь?
механизмы разные, а компилятор C++ иногда догадывается, что надо вставить код, который преобразует одно в другое.

Serab

Один загадочный пример не годится
Слушай, . Вот ты не знаешь как это работает, пишешь как раз ничем не обоснованные утверждения, удосужившись заглянуть только в приветственную страничку MSDN'а про исключения. Уже того, что я показал тебе программу достаточно. Учитесь искать информацию.
Еще ты врешь.
Предлагаю всем желающим убедиться, запустив программу

#include <tchar.h>
#include <iostream>
#include <excpt.h>
#include <windows.h>

using namespace std;

void t
{
throw 777;
}

void f
{
__try
{
t;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
cout << " sucks" << endl;
}
}

int main
{
try
{
f;
} catch (...)
{
cout << " sucks" << endl;
}
return 0;
}

Можно отвечать кратко: единственная строчка, которая появляется на экране.
Компилировать студией. Не юлить =) Я тоже могу не изменяя этих строчек заставить выводиться все что угодно.

Serab

механизмы разные, а компилятор C++ иногда догадывается, что надо вставить код, который преобразует одно в другое.
try/catch компилятор Visual C++ реализует через SEH. Точка. Сам же Рихтера советуешь :smirk:
Вот от тебя не ожидал.

karkar

Извини, ошибся. Забыл про другое изменение исходника. Действительно, выводит то же, что у тебя.

Dasar

try/catch компилятор Visual C++ реализует через SEH. Точка.
с этим не спорю.

Serab

Извини, ошибся. Забыл про другое изменение исходника. Действительно, выводит то же, что у тебя.
Что выводит напиши :smirk:

Dasar

вот тебе кстати на засыпку
что сделает _tmain расскоментированный, и что сделает _tmain закоментированный?
и почему поведение разное, если ты говоришь, что механизм один и тот же?

#include <iostream>
#include <windows.h>

int z = 5;

void f
{
int x = 4/z;
}


int _tmain(int argc, _TCHAR* argv[])
{
try
{
z = 0;
f;
std::cout << "ok" << std::endl;
}
catch (...)
{
std::cout << "catch" << std::endl;
}

return 0;
}

//int _tmain(int argc, _TCHAR* argv[])
//{
// __try
// {
// z = 0;
// f;
// std::cout << "ok" << std::endl;
// }
// __except (EXCEPTION_EXECUTE_HANDLER)
// {
// std::cout << "catch" << std::endl;
//
// }
//
// return 0;
//}


Serab

Предполагаю, что зависит от ключа компилятору.
Точнее: можно так задать ключ, что оба будут работать одинаково.
Еще точнее: ключ /EHa позволяет catch(...) перехватывать исключения, брошенные RaiseException etc.
upd: так и вышло.

Dasar

Предполагаю, что зависит от ключа компилятору.
ты б еще ответил, что "зависит от положения пятен на солнце".
сказал А, говори и B - какие ключи и в чем будет разница.
зы
до этого ты утверждал, что механизм один и тот же - и не про какие ключи речь не шла.

Serab

сказал А, говори и B - какие ключи и в чем будет разница.
Прочитай апдейт, устраивает?

Serab

до этого ты утверждал, что механизм один и тот же - и не про какие ключи речь не шла.
Неправда, пруфлинк :confused:
Я утверждал, что try/catch реализован через SEH, откуда следует, что throw-исключения можно отловить __except. И _сразу же_ сказал, что чтобы было наоборот нужны телодвижения. Потом подправил (время там указано что достаточно ключа компилятора, если программист не искушен.

Dasar

И _сразу же_ сказал, что чтобы было наоборот нужны телодвижения.
ну, да, если тред прочитать заново, то непонятно о чем спор идет. :)
это я намекаю на то, что твои посты почти везде дополненные по сравнению с тем, на что шли замечания.
зы
если по существу, то да:
C++-исключения сделаны поверх SEH
C++ catch не ловит голые SEH-исключения без спец. телодвижений.
спец. телодвижения, в виде, включения опции /Eha просаживают производительность C++-приложения где-то в 2 раза и при этом не помогает правильной размотке C++-стека, и часть деструкторов все равно не вызывается
зы
2 раза было на vc6, сейчас может лучше

Serab

часть деструкторов все равно не вызывается
Про это читал где-то, но у себя проверить не удалось.
А есть пример кода, который компилируется, но деструктор не вызывается? Вообще говоря момент принципиальный, сыконтно как-то =)

Serab

если по существу, то да:
C++-исключения сделаны поверх SEH
C++ catch не ловит голые SEH-исключения без спец. телодвижений.
спец. телодвижения, в виде, включения опции /Eha
Еще можно доснобствовать и сказать, что в release-версии при делении на ноль не будет брошено HW-исключение и будет выведено «ok» =)

Serab

это я намекаю на то, что твои посты почти везде дополненные по сравнению с тем, на что шли замечания.
Ну это да, надо привыкнуть отвечать, а не править, но все правки в этом треде я делал до того как последуют ответы на соответствующие посты. Просто тут в некоторый момент все начали усердно постить и правда можно было запутаться.

Dasar

А есть пример кода, который компилируется, но деструктор не вызывается? Вообще говоря момент принципиальный, сыконтно как-то =)
это я наврал все-таки
опять же с vc6 опыт тянется.
в vc8 у меня не получилось потерять, но производительность-да, сажается сильно при включенном /EHa, т.к. в каждую функцию где используются классы с деструктором вставляется код, который навешивает SEH-обработчик

Dasar

Еще можно доснобствовать и сказать, что в release-версии при делении на ноль не будет брошено HW-исключение и будет выведено «ok» =)
если речь про мой пример, то - да
но это потому что x не используется и оптимизатор просто выкидывает само деление.

Serab

если речь про мой пример, то - да
но это потому что x не используется и оптимизатор просто выкидывает само деление.
да, ты прав, действительно думать надо =)
Оставить комментарий
Имя или ник:
Комментарий: