Расширение класса std :: exception: программа не выполнит соответствующий обработчик catch - PullRequest
3 голосов
/ 06 декабря 2011

Я получил класс из std :: exception:

class exc : public std::exception
{
public:
    exc(const text::_char *) throw();
    exc(const exc &) throw();
    virtual ~exc() throw();

    text::_char *m_what;
};

У меня есть две функции-обертки для выдачи типа исключения:

PS: dbg_out ссылается на std :: cout. текст является потомком std :: basic_string << char >>.

void throw_exception(const text::_char *p_format, ...)
{
    va_list l_list;

    text l_message;

    va_start(l_list, p_format);
    l_message.format_va(p_format, l_list);
    va_end(l_list);
    throw exc((const text::_char *)l_message);
}

void throw_exception_va(const text::_char *p_format, va_list p_list)
{
    text l;
    exc l_exc((const text::_char *)l.format_va(p_format, p_list));

    dbg_out << l_exc.m_what;
    throw l_exc;
}

И основная функция:

int main(int, char **)
{
    try
    {
        throw_exception("hello world!");
        return 0;
    }
    catch(const std::exception &p)
    {
        return 0;
    }
}

Моя программа падает с этим сообщением:

hello world!
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Я использую компилятор gcc (последняя версия MinGW)

Моя программа не вводит обработчик перехвата в основную функцию. Он не вызывает конструктор копирования класса exc. Похоже, код, сгенерированный gcc, не распознает exc как потомка std :: exception

Что я делаю не так?

Ответы [ 2 ]

1 голос
/ 06 декабря 2011

Держу пари, ваша проблема в этой строке:

throw exc((const text::_char *)l_message);

Вы упомянули text происходит от basic_string<char>. Не поддерживается приведение от basic_string<char> до const char*. Так что, если вы не предоставите свой собственный оператор преобразования в производном классе, вы будете в некотором роде неопределенным / неопределенным поведением. Попробуйте изменить вышеприведенную строку на:

throw exc(l_message.c_str());
0 голосов
/ 06 декабря 2011

Это то, что я написал в дек. Пятый:

Память, скопированная конструктором exc, была удалена перед копированием. Нарушение прав доступа гарантировано! Я узнал еще одну вещь об этом замечательном языке программирования (что происходит за кулисами, когда вы «бросаете exc (some_deleted_memory)»).

<< конец дек. Пятые >>

Это не настоящая проблема. Настоящая проблема в том, что gcc-компилятор (с параметрами:)

    gcc -fexceptions -Wnoexcept -fno-use-cxa-get-exception-ptr -include .\pch.h -g3 *.cpp 
    -l libstdc++ -o vlb.exe

не любит исключения, которые будут выбрасываться против спецификаций throw () объявлений функций. Когда throw_exception () объявляется как

    void throw_exception() throw(const std::exception &);

все хорошо.

Я всегда думал, что (по крайней мере, программные) исключения могут возникать при каждом вызове, и процедура размотки стека должна быть в состоянии справиться с этим. Мне не нравится то, что мне нужно было бы указать, какой тип исключений может оставить функцию для каждой функции, которую я пишу.

Так или иначе, я должен быть в состоянии указать, что любой тип программного исключения может оставить любую функцию, которую я пишу, в командной строке gcc. Но как? Я опубликую новый вопрос для этой новой темы.

Спасибо всем, кто думал обо мне.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...