MSVC 10 и MSVC 9 генерируют предупреждающее сообщение уровня 4 при компиляции моей структуры исключений, хотя поведение программы кажется правильным.Структура исключений довольно большая и сложная, но мне удалось свести ее к сути.Это полная программа, которую вы можете скомпилировать и запустить в VS10
#include <cstdlib>
#include <stdexcept>
#include <string>
#include <iostream>
#include <sstream>
using namespace std;
namespace ex
{
class generic_error : virtual public std::exception
{
public:
generic_error(int thread_id) : thread_id_(thread_id) {}
const char* what() const throw()
{
static std::string msg;
stringstream ss;
ss << "generic error in thread #" << thread_id_;
msg = ss.str();
return msg.c_str();
}
int thread_id_;
};
template<class EX>
class traced_error : virtual public std::exception, virtual public EX
{
public:
traced_error(int line, const EX& ex): EX(ex), line_(line) { }
const char* what() const throw()
{
static std::string msg;
stringstream ss;
ss << "traced error on line " << line_ << " : '" << EX::what() << "'";
msg = ss.str();
return msg.c_str();
}
int line_;
};
template<class EX> traced_error<EX> make_traced_error(int line, const EX& ex)
{
return traced_error<EX>(line, ex);
}
}
int main()
{
try
{
throw ex::make_traced_error(__LINE__, ex::generic_error(234));
}
catch( const ex::generic_error& gex )
{
cout << "gex = " << gex.what();
return 2;
}
catch( const exception& ex )
{
cout << ex.what();
return 1;
}
}
При компиляции строки throw ex::make_traced_error(__LINE__, ex::generic_error(234));
компилятор выдает:
1>hacks_vs10.cpp(51): warning C4673: throwing 'ex::traced_error<EX>' the following types will not be considered at the catch site
1> with
1> [
1> EX=ex::generic_error
1> ]
Одной из целей этой библиотеки исключений являетсядобавить информацию исходного файла к каждому выброшенному исключению.Я использую макрос, который оценивается как throw ex::make_traced_error(__FILE_, __LINE__, ex);
, но это не было необходимо для репликации предупреждения компилятора.
make_traced_error
создает экземпляр класса шаблонного исключения, параметр шаблона для которого является генерируемым исключением, в данном случае generic_error
.Очевидно, что если я просто выброшу простую generic_error
, то компилятор будет счастлив, но я не хочу этого делать.
В чем причина и следствие этого предупреждения?Компилятор не прав или мой код?Я должен отметить пару вещей здесь.
Во-первых, когда я выполняю этот код, он делает то, что я ожидаю.Блок захвата generic_error
вызывается вместо общего блока exception
, и вывод программы:
gex = отслеженная ошибка в строке 51:
Во-вторых, когда я компилирую этот код с помощью онлайн-компилятора Comeau , он компилируется без ошибок или предупреждений, предлагая мне, что мой код соответствует стандартам и легален для C ++.Правильное предположение?
'общая ошибка в потоке # 234'
Наконец, я видел статью базы знаний MS об этом предупреждении.Но объяснение М.С. было полностью неудовлетворительным (оно не объясняло причину предупреждения), и их решение недопустимо - они говорят, что я должен просто бросить стрит generic_error
.