Форум программистов, компьютерный форум CyberForum.ru

mingw32, SEH, std::exception, setjmp/longjmp, signal - C++

Восстановить пароль Регистрация
Другие темы раздела
C++ Работа с рядками http://www.cyberforum.ru/cpp-beginners/thread450789.html
Дан текст. Групы символов, розделеные пропусками которые не содержат пропусков всередині себя, будем называть словами словами.Посчитать , сколько слов в начинаются и заканчиваются одной и той же буквой.
C++ Работа с рядками Дан текст, который составляется из букв, цифр и пропусков. Последовательность которая начинается символом и в которой нет пропусков назовём идентификатором. Вывести все идентификаторы которыесодержатся в тексте и подсчитать сколько раз каждый из них встречался. http://www.cyberforum.ru/cpp-beginners/thread450786.html
C++ Заполнить матрицу по образцу
Заполнить матрицу размером n*m числами 1,2,3, … n*m, оюходя её соответственно варианту:
C++ В одномерном массиве найти наименьшую по длине убывающую последовательность
В одномерном массиве найти наименьшую по длине убывающую последовательность
C++ как можно реализовать это в коде? http://www.cyberforum.ru/cpp-beginners/thread450776.html
Здравствуйте. Если вам не трудно скажите как можно в коде реализовать это: Вариантов множество. Например, заводится массив с указателями на текущие элементы лент; затем с использованием этого просматриваются текущие элементы лент и среди них выявляется минимальный; после "вытаскивания" минимального элемента сдвигается соответствующий указатель на один элемент и процесс повторяется.
C++ Из vector в массив. Доброго всем утра коллеги! Собственно, есть вектор с шаблоном std::vector<float> vect; и теперь надо каждый из элементов вектора передать в массив for(unsigned int i=0; i<vect.size(); i++){ float arr={0, 0, 0}; arr = vect.at(i)//пишет: error C2106: '=' : left operand must be l-value подробнее

Показать сообщение отдельно
cyberguz
6 / 6 / 0
Регистрация: 01.12.2010
Сообщений: 105
22.02.2012, 11:01     mingw32, SEH, std::exception, setjmp/longjmp, signal
Начал разбираться с вопросом - как понял - есть несколько вариантов: (в порядке обнаружения мною)

1) LibSEH - работает.
http://www.programmingunlimited.net/...page=mingw-seh

2) <eh.h>, _set_se_translator - долго мучался с заголовками, а когда скомпилил - не смог слинковать.

3) <excpt.h> - видимо, недоделанная версия LibSEH - работает неадекватно (или я чего-то не понял).

4) И тут я вспомнил про сигналы и setjmp/longjmp, накидал себе такой код:

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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
class SignalExceptionGuard
{
public:
    static const int handled_signals [];
    SignalExceptionGuard ();
    virtual ~SignalExceptionGuard ();
    /*
     * Можно выбрасывать в качестве исключений объекты классов,
     * которые имеют конструкторы от int.
     */
    template <class ExceptionType>
    inline void Try (int sig_code) throw() {if(sig_code) throw ExceptionType(sig_code);}
    /*
     * Для использования в качестве параметра в setjmp.
     */
    inline operator int* () {return jb;}
    /*
     * Преобразовывает другие виды исключений в стандартные исключения С++.
     */
    static inline void Try (std::function<void()> fn) throw()
    {
        SignalExceptionGuard seg;
        seg.Try<Exception>(setjmp(seg));
        fn();
    }
    /*
     * Фактически - это указатель на вызов setjmp, в который вернётся управление
     * при вызове longjml с этим указателем в ккачестве параметра.
     */
    jmp_buf jb;
private:
    /*
     * Uncopyable, unassignable.
     */
    SignalExceptionGuard (const SignalExceptionGuard&);
    SignalExceptionGuard& operator= (const SignalExceptionGuard&);
    /*
     * Для каждого потока свой стек объектов SignalExceptionGuard и отдельный указатель на верхушку.
     */
    static __thread SignalExceptionGuard* curr;
    /*
     * Обработчик сигнала.
     */
    static void sig_handler (int sig_code);
    SignalExceptionGuard* prev;
};
 
const int SignalExceptionGuard::handled_signals [] = {
//  SIGINT
//  SIGILL
//  SIGTERM
//  SIGBREAK
//  SIGABRT
/* floating point exception, e.g. zero-division */
    SIGFPE,
/* segmentation fault */
    SIGSEGV
};
 
__thread SignalExceptionGuard* SignalExceptionGuard::curr = nullptr;
 
void SignalExceptionGuard::sig_handler (int sig_code)
{
    if (curr) longjmp(curr->jb, sig_code);
}
 
SignalExceptionGuard::SignalExceptionGuard () :
    jb({0}), prev(curr)
{
    if (!curr)
    {
        for (size_t i = 0; i < COUNT(handled_signals); i++)
            signal(handled_signals[i], sig_handler);
    }
    curr = this;
}
 
SignalExceptionGuard::~SignalExceptionGuard ()
{
    curr = prev;
}
Тоже вроде бы работает.



ИТОГО:
Ни один из этих способов не раскручивает плюсовый стек поравильно, т.е. не вызывает деструкторы.
Очевидно, что внутри своего кода надо делать по-человечески - проверять значения и кидать плюсовые исключения.
Первый и четвёртый позволяют адекватно продолжить выполнение если, например, в вызове из сторонней либы что-то сломалось. Тем более, если либо загружена вручную (как плагин).


Уважаемые специалисты, дополните, пожалуста, меня или поправте, если я не прав.

К тому-же очень интересует вопрос - при выкидывании всех ли виндовых структурных исключений вызываются обработчики сигналов, и когда ещё в винде вызываются обработчики сигналов?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
Текущее время: 11:49. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru