Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 4.80/25: Рейтинг темы: голосов - 25, средняя оценка - 4.80
0 / 0 / 0
Регистрация: 09.10.2020
Сообщений: 26

Не работает перехват исключений try catch в GCC

15.10.2020, 17:11. Показов 5836. Ответов 29

Студворк — интернет-сервис помощи студентам
Из блока try catch вызывается процедура proc в которой возникают разного вида исключения, но ни одно из них не перехватывается этим блоком.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
long double res; 
 
 try 
  {
    res = proc(); 
  }
 catch (...) 
 {
 
 }
 
 
long double proc();
{
 
  long double res,x;
  int32 n;
  long double ve[10];
 
 
  x=1.123;
  n = 5;
 
/*
 В процедуре могут возникать различные исключения,например,
 деление на ноль: 
    res = x/sin(x-x); 
    res = n/(n-5);
 
 переполнение:
   res = pow(x,x*1000);
 
 неверная операция:
   res = pow(-x,x);
 
 ошибка доступа:
   res = x+ve[20]; 
*/
 return res;
}
Ни одно из этих исключений не перехватываются в try , catch и приводят к аварийному завершению программы.
Что я делаю не так?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
15.10.2020, 17:11
Ответы с готовыми решениями:

не работает перехват исключений
В программе идет подключение к базе intebase через SqlConnect (sqlflat). SqlConnect находиться в модуле modConnect Если...

Не работает обработка исключений Try Catch для Convert.ToInt32("123.4a")
подскажите почему не срабатывает исключение, не какой реакции почему Imports System.Exception Public Class Form1 Private...

Обработка исключений try catch
Здравствуйте. Программа с использованием CLR. Суть работы очень проста - в три TextBox'а вводятся числа, они сравниваются. Результат...

29
0 / 0 / 0
Регистрация: 09.10.2020
Сообщений: 26
16.10.2020, 13:54  [ТС]
Студворк — интернет-сервис помощи студентам
"Зачем писать код, который в обычной ситуации должен вываливаться? Обработка исключений - очень затратная и медленная операция, намного более медленная чем простые условные переходы при обнаружении недопустимых данных."

Ну,...так работает логика программы. Она верная и иначе нельзя. В том то и дело, что программа не должна "вываливаться", а должна быть информация об ошибке вычислений без аварийного завершения. Это нормальная, контролируемая работа программы , так и должно быть.
А вот перехват ошибок медленный только в C/C++ по тем примерам , которые приводят. В Дельфи он работает через прерывания и абсолютно не замедляет работу программы.
PS
Не ужели за всё время никто в C/C++ не написал класс перехвата исключений через прерывания, который работает также, как в Дельфи? Чтобы просто подключить его include<> , а всё остальное, как в Дельфи. Мне нужно только для Windows.

Добавлено через 5 минут
"Просто проверяй на ноль перед делением, на nullptr перед обращением к указателю и т.д. И делай throw, если ошибка. Поверь, так будет намного лучше. Программа будет читабельнее и надёжнее."

Проверка proc() на вычислительные ошибки, а также на AccessViolation принципиальна не возможна.
Формула в этой процедуре задаётся извне пользователем и содержание её неизвестно. Также невозможно после каждого одиночного вычисления проверять результат на исключение. Такой вариант предлагался выше. Это очень сильно замедляет работу программы. Нужна реализация только перехвата исключений только через прерывания.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
16.10.2020, 13:57
Цитата Сообщение от Dmanx Посмотреть сообщение
перехвата исключений через прерывания, который работает также, как в Дельфи?
1) Используйте MSVC
2) Включите в настройках трансляцию SEH в C++ execptions
3) Профит.

PS. Про GCC в таком случае можно забыть. Он это не поддерживает.

Цитата Сообщение от Dmanx Посмотреть сообщение
Не ужели за всё время никто в C/C++ не написал класс
Еще раз скажу, что манера обращаться с программными ошибками Delphi не есть панацея, есть другие стратегии. А вам просто нужно "именно так и никак иначе", но это ваша проблема, а не С++ или чего-то еще.
0
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.10.2020, 14:01
Цитата Сообщение от DrOffset Посмотреть сообщение
Бубен нужен, только если вы делаете что-то противоестественное. Сам по себе дизайн, где по умолчанию в одну кучу собраны и логические исключения и аппаратно-системные, нельзя назвать удачным. Так что удобство, которое дает делфи, на самом деле играет злую шутку с вашим кодом.
Если быть справедливым, то ведь и в python так и в других языках вроде тоже так.
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
16.10.2020, 14:03
Цитата Сообщение от Dmanx Посмотреть сообщение
Формула в этой процедуре задаётся извне пользователем и содержание её неизвестно. Также невозможно после каждого одиночного вычисления проверять результат на исключение. Такой вариант предлагался выше. Это очень сильно замедляет работу программы. Нужна реализация только перехвата исключений только через прерывания.
В неуправляемой среде, что в Delphi, что в С++, и т.д. сделать такую проверку безопасно и при этом сохранить работоспособность приложения можно только одним способом: создать дочерний процесс, провести вычисление пользовательской неизвестной функции там.
Именно так сейчас поступают все современные браузеры, (например чтобы не уронить всю программу, если в одной вкладке "заглючил" какой-то сторонний плагин).
А ваш подход маскирует проблему и все равно не защитит, особенно если пользователь будет достаточно изобретателен.

Добавлено через 2 минуты
Цитата Сообщение от Avazart Посмотреть сообщение
Если быть справедливым, то ведь и в python так и в других языках вроде тоже так
Это совершенно разные вещи. Python и другие языки (я так понимаю речь о C# и подобных), работают в изолированной среде и там это имеет совсем другие эффекты, никаких катастрофических последствий таким образом там получить нельзя, т.к. весь процесс там контролирует интерпретатор или виртуальная машина.
1
Эксперт С++
 Аватар для Avazart
8489 / 6156 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
16.10.2020, 14:06
Цитата Сообщение от Dmanx Посмотреть сообщение
А вот перехват ошибок медленный только в C/C++ по тем примерам , которые приводят. В Дельфи он работает через прерывания и абсолютно не замедляет работу программы.
А с чего Вы взяли что что в делфи нет "замедления"?

Добавлено через 47 секунд
Цитата Сообщение от DrOffset Посмотреть сообщение
Это совершенно разные вещи. Python и другие языки (я так понимаю речь о C# и подобных), работают в изолированной среде и там это имеет совсем другие эффекты, никаких катастрофических последствий таким образом там получить нельзя, т.к. весь процесс там контролирует интерпретатор или виртуальная машина.
Мм... какая разница если Вы говорили про логику работы и "сгребание в кучу"?
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
16.10.2020, 14:08
Цитата Сообщение от Avazart Посмотреть сообщение
Мм... какая разница если Вы говорили про логику работы.
А давайте вы прочитаете ветку сначала?
Я говорил о том, злом является мешать в одну кучу контролируемые логикой программы исключительные ситуации и неконтролируемые в общем случае аппаратно-системные реакции на ошибочный код.
В управляемых средах все ошибки могут быть контролируемы логикой программы. Это гарантирует среда исполнения. Поэтому там это нормально.
0
зомбяк
 Аватар для TRam_
1585 / 1219 / 345
Регистрация: 14.05.2017
Сообщений: 3,940
16.10.2020, 15:16
Цитата Сообщение от Dmanx Посмотреть сообщение
Формула в этой процедуре задаётся извне пользователем и содержание её неизвестно
То есть речь о том, что формула встраивается из независимо скомпилированного плагина, и в этой формуле могут быть ошибки, правильно?
0
0 / 0 / 0
Регистрация: 09.10.2020
Сообщений: 26
16.10.2020, 19:46  [ТС]
"То есть речь о том, что формула встраивается из независимо скомпилированного плагина, и в этой формуле могут быть ошибки, правильно?"

Да. Более подробно: передаётся извне адрес скомпилированного кода, производящий вычисления.
Процедура proc выглядит так:
long double eval(PVOID addr);
{
asm
call addr
end;
}

Вычисления eval в большинстве случаев происходят в цикле с изменяющимися переменными.

long double res;

for(...)
{
x1 = ...;
x2 = ...;
...
res = ...eval(addr)...; //выражение, содержащее eval
}
x1,x2,... - переменные , участвующие в вычислениях в переданном извне скомпилированном коде. Возможные типы этих переменных: целые, с плавающей точкой, массивы
..
func(x1,x2,...i1,i2,...v1,v2,...)
Передаётся адрес 'addr' этой функции, но переменные, участвующие и в основной программе и в этой функции - общие.


В ходе расчётов могут возникать различные исключения: FPU и AccessViolation <- но это исключение уже будет ошибкой программиста, а не вычислительной. При исключении нужно выдать подробную информацию с мгновенными значениями переменных. При этом, программа не должна аварийно завершаться.
Поэтому удобно обернуть весь этот цикл в блок:
На Дельфи:
try
//условный пример:
for i = 0 to N do
begin
x1:=i*1.25;
x2:=x1*sin(x1)
res:=res+eval(addr);
end;
except
on E: EZeroDivide do ErrorCode:=E_ZeroDivide;
on E: EInvalidOp do ErrorCode:=E_InvalidOp;
on E: EOverFlow do ErrorCode:=E_OverFlow;
on E: EAccessViolation do ErrorCode:=E_AccessViolation;
end;
0
19506 / 10109 / 2464
Регистрация: 30.01.2014
Сообщений: 17,834
16.10.2020, 21:02
Цитата Сообщение от Dmanx Посмотреть сообщение
На Дельфи
https://docs.microsoft.com/ru-... ew=vs-2019
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <windows.h>
 
LONG ExceptFilter(DWORD except_code, PEXCEPTION_POINTERS except_info, int * errcode)
{
    // здесь может быть и более сложный анализ
    switch(except_code)
    {
    case EXCEPTION_FLT_OVERFLOW:          // E_OverFlow
    case EXCEPTION_FLT_DIVIDE_BY_ZERO:    // E_ZeroDivide
    case EXCEPTION_ACCESS_VIOLATION:      // E_AccessViolation
    case EXCEPTION_FLT_INVALID_OPERATION: // E_InvalidOp
        *errcode = except_code;
        return EXCEPTION_EXECUTE_HANDLER;
    }
    return EXCEPTION_CONTINUE_SEARCH;
}
 
int main()
{
    int ErrorCode = 0;
    __try
    {
        // ваш код
    }
    __except(ExceptFilter(GetExceptionCode(), GetExceptionInformation(), &ErrorCode))
    {
        // обработчик
    }
}
Но, как я уже сказал, и ваше решение в Delphi, и этот код не дадут 100% гарантии, что приложение после перехвата останется работоспособным. Некоторые ошибки вы сможете так безопасно поймать, но далеко не все. А если код поступает от пользователя, то он может написать все что угодно, в том числе что-то, что будет угрожать безопасности вашего приложения.

Поэтому единственный надежный вариант, выносить все опасные вычисления в другой процесс. Анализировать состояние процесса на предмет возникновения в нем нештатных ситуаций. С основным приложением организовать взаимодействие через один из доступных вариантов IPC. Да, это гораздо сложнее сделать, чем то, на что вы рассчитывали, но только так это не будет профанацией.

Также существуют готовые решения по предоставлению безопасного окружения для непроверенных вычислений. Можно погуглить по ключевому слову "Sandboxing" (или начать отсюда). Вот пример такого решения: https://github.com/google/sandboxed-api
1
415 / 150 / 48
Регистрация: 02.06.2016
Сообщений: 364
18.10.2020, 09:55
Цитата Сообщение от Dmanx Посмотреть сообщение
Мне нужно только для Windows
Для MinGW-64.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <stdio.h>
#include <windows.h>
 
extern "C" int exc(_In_ EXCEPTION_POINTERS *lpEP);
 
int exc(_In_ EXCEPTION_POINTERS *lpEP)
{
    if (lpEP->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
        printf("Divide by zero");
 
    return EXCEPTION_EXECUTE_HANDLER;
}
 
 
int main(int argc, char *argv[])
{
    __try1(exc)
    {
        int x=1/0;
    }
    __except1;
 
    return 0;
}
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
18.10.2020, 09:55

Gcc и обработка исключений
Есть пустой проект, компилируемый через QtCreator с gcc 4.9.2, под Дебиан. В него добавляется абсолютно пустая функция void...

try, throw, catch...обработка исключений
помогите разобраться с обработкой исключений...при вводе пароля больше 10 символов должна быть непредвиденная ошибка, пытаюсь ее поймать,но...

Один catch для нескольих исключений
У меня есть функция, которая бросает исключения, если выполняется условие. Эту функцию я вызываю в main() несколько раз. Для каждого вызова...

Обработка исключений Конструкция try.catch.finally
Добрые день, помогите пожалуйста Вводится время в текстбоксе(например 22:23) и в отдельном текстбоксе вводятся минуты Вывести какое...

Отлов исключений без использования try/catch
Всем привет. Есть форма и не сколько кнопок. При нажатии на каждой из кнопок будет вызвано исключение. Требуется: 1. ловить все...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
30
Ответ Создать тему
Новые блоги и статьи
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр.
Jin X 06.09.2026
Скрипты Tampermonkey для CyberForum, ChatGPT, Claude и пр. Работая с форумом и нейросетями в браузере часто хочется что-то подкорректировать или добавить какого-то функционала. Ниже прикреплён. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru