Russian Qt Forum
Май 06, 2024, 09:14 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Исключения - как правильно готовить?  (Прочитано 7595 раз)
Dmitry_Panoff
Гость
« : Февраль 28, 2006, 11:22 »

Qt-4.1, gcc-3.4.2 (mingw-special), win2003 enterprise
Имеем объявление и реализацию класса А в файле 1.h и 1.cpp соответственно:
Код:

class A {
public:
  class xClass { };
  void f1()throw();
};


Код:

..
A::f1()throw()
{
  if (улсовие) throw xClass
}


main.cpp
Код:

A a;
...
try
{
 a.f1();
}
catch (A::xClass)
{
  Обработка исключения
}

при запуске винда выдает сообщение:
Цитировать

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

Получается, что любое выкидываемое функцией исключение компилятор понимает как неожиданное и вызывает дефолтный виндовый обработчик, который и пишет мне вот такие сообщения.
Указывал throw(xClass) в определении и реализации класса, объявлял класс без throw() вообще - все едино.
Вопрос: как указать компилятору, что на данное исключение есть свой обработчик и не надо аварийно выкидывать прогу?
Записан
kolobok0
Гость
« Ответ #1 : Февраль 28, 2006, 19:03 »

вот цитата из МСДН...

Код:


Exception specifications are used to provide summary information about what exceptions can be thrown out of a function. For example:

  Copy Code
void MyFunction(int i) throw(...);
 

An exception specification with an empty throw, as in

  Copy Code
void MyFunction(int i) throw();
 

tells the compiler that the function does not throw any exceptions. It is the equivalent to using __declspec(nothrow). For example:

  Copy Code
// exceptions_trycatchandthrowstatements3.cpp
#include <stdio.h>

void empty() throw()
{
    puts("In empty()");
}

void with_type() throw(int)
{
    puts("Will throw an int");
    throw(1);
}

int main()
{
    try {
        empty();
        with_type();
    }catch (int){
        puts("Caught an int");
    }
}
 

Visual C++ departs from the ANSI Standard in its implementation of exception specifications. The following table summarizes Visual C++'s implementation of exception specifications:

Exception specification  Meaning  
throw()
 The function does not throw an exception.
 
throw(...)
 The function can throw an exception.
 
throw(type)
 The function can throw an exception of type type. However, in Visual C++ .NET, this is interpreted as throw(...). See Function Exception Specifiers.
 

If exception handling is used in an application, there must be one or more functions that handle thrown exceptions. Any functions called between the one that throws an exception and the one that handles the exception must be capable of throwing the exception.

The throw behavior of a function depends on the following factors:

Whether you are compiling the function under C or C++.


Which /EH compiler option you use.


Whether you explicitly specify the exception specification.


Explicit exception specifications are not allowed on C functions.

The following table summarizes the throw behavior of a function:

Function  /EHsc  /EHs  /EHa  /EHac  
C function
 throw()
 throw(...)
 throw(...)
 throw(...)
 
C++ function with no exception specification
 throw(...)
 throw(...)
 throw(...)
 throw(...)
 
C++ function with throw() exception specification
 throw()
 throw()
 throw(...)
 throw(...)
 
C++ function with throw(...) exception specification
 throw(...)
 throw(...)
 throw(...)
 throw(...)
 
C++ function with throw(type) exception specification
 throw(...)
 throw(...)
 throw(...)
 throw(...)
 

Example
  Copy Code
// exception_specification.cpp
// compile with: /EHs
#include <stdio.h>

void handler()
{
    printf_s("in handler\n");
}

void f1(void) throw(int)
{
    printf_s("About to throw 1\n");
    if (1)
        throw 1;
}

void f5(void) throw()
{
    try {
        f1();
    } catch(...) {
        handler();
    }
}

//
// invalid, doesn't handle the int exception thrown from f1()
// void f3(void) throw()  
// {
//   f1();
// }
//

void __declspec(nothrow) f2(void)
{
    try {
        f1();
    } catch(int) {
        handler();
    }
}

// only valid if compiled without /EHc
// /EHc means assume extern "C" functions don't throw exceptions
extern "C" void f4(void);
void f4(void)
{
    f1();
}

int main()
{
    f2();

    try {
        f4();
    } catch(...) {
        printf_s("Caught exception from f4\n");
    }
    f5();
}
 

  Copy Code
About to throw 1
in handler
About to throw 1
Caught exception from f4
About to throw 1
in handler
 



надеюсь ситуёвина прояснилась ?

с уважением
(круглый)
Записан
Dmitry_Panoff
Гость
« Ответ #2 : Февраль 28, 2006, 22:02 »

kolobok0
Цитировать
надеюсь ситуёвина прояснилась ?

Ммм, не совсем...
Может я чего-то недопонимаю, но:
1. Я использую gcc, а не компилятор из вижуала.
2. Я  написал, что явно прописывал какое исключение функция может выкидывать - все равно вызывается стандартный обработчик...

Может при сборке гцц дополнительные ключи надо указывать?
Записан
kolobok0
Гость
« Ответ #3 : Март 01, 2006, 14:19 »

чтоб компилятор не сыпал вонингами и вызывался бы Ваш обработчик попробуйте следующие варианты...
1) не указывать у функции исключения..
2) обьявить у функции любые типы исключений...

и то и то дышит...

с уважением
(круглый)
ЗЫ
Если коды ошибок совпадают, и по идентификатору и по смыслу - то думаю особенной рояли не играет, чем Вы пользуетесь при компиляции.
Записан
Вудруф
Гость
« Ответ #4 : Март 02, 2006, 11:33 »

Не указывать классы исключений, которые будут генерироваться - плохой тон. В то же время генерация исключений внутри функции, которая объявлена как не генерирующая их - ошибка. И обрабатывается она правильно.
Не понятно, почему при объявлении конкретного класса или вообще без throw() не работает. Сейчас проверю.

добавлено спустя 55 минут:

 Работает...
---------------------
a.h:
---------------------
#ifndef A_H
#define A_H

class A
{
public:
   class xClass {};
   void f1() throw (xClass);
};

#endif

---------------------
a.cpp:
---------------------
#include "a.h"

void A::f1() throw (A::xClass)
{
   throw xClass();
}

---------------------
main.cpp:
---------------------
#include <iostream>

#include "a.h"

int main()
{
   A aClass;
   try
   {
      aClass.f1();
   }
   catch (const A::xClass &)
   {
      std::cout << "OK\n";
   }
   catch (...)
   {
      std::cerr << "ERROR\n";
   }
}

добавлено спустя 1 минуту:

 Выводит "ОК"
Записан
Dmitry_Panoff
Гость
« Ответ #5 : Март 04, 2006, 21:37 »

Посидев и покопавшись в доках, поигравшись с простыми примерам по типу приведенного Вудруфом, я выяснил следующее: в gcc для поддержки исключений надо указывать флаги -fexception -frtti. Они правда в мэйкфайле и прописывались, вместе с указанием Qt использовать исключения (CONFIG += exceptions). Но все это ни к чему не привело - указывай тип исключения, прописывай просто ключевое слово throw() или не прописывай вообще ничего - результат один - стандартный виндовый обработчик.
Посему, пришлось мне отказаться от исключений. Это, правда, нескоько загромождает код, но что делать... Из-за чего возникает сей глюк: Qt, mingw, винда, мое недопонимание - мне выяснять недосуг...
В общем, отрицательный результат - тоже результат. Всем большое спасибо за помощь.
Записан
Вудруф
Гость
« Ответ #6 : Март 06, 2006, 07:51 »

Я использовал прерывания в Qt-программах под Windows, компилируя всё это MinGW. Всё работало...
Единственный вариант, который я могу придумать - исключение не ловится, или по-другому, функция, генерирующая исключение, вызывается не из блока try..., или catch пытается ловить другой тип исключения, нежели ты генерируешь.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.044 секунд. Запросов: 20.