Joh*_*ing 5 c++ visual-studio-2010 visual-studio-2008
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;
}
}
Run Code Online (Sandbox Code Playgroud)
在编译该行时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> ]
Run Code Online (Sandbox Code Playgroud)
此异常库的目标之一是将源文件信息附加到每个抛出的异常.我使用一个评估为的宏throw ex::make_traced_error(__FILE_, __LINE__, ex);,但没有必要复制编译器警告.
make_traced_error实例化一个模板异常类,在这种情况下,模板参数是抛出的异常generic_error.显然,如果我简单地抛出一个简单generic_error的编译器很高兴,但这不是我想要做的.
这个警告的原因和结果是什么?编译器错了,还是我的代码?我应该在这里注意几件事.
首先,当我执行此代码时,它会执行我期望它执行的操作.的generic_errorcatch程序块被称为而不是一般的exception块,并且该程序的输出结果是:
第51行的gex =跟踪错误:
其次,当我使用Comeau在线编译器编译此代码时,它编译时没有错误或警告,向我建议我的代码是符合标准且合法的C++.正确的假设?
线程#234中的一般错误
最后,我已经看过有关此警告的MS知识库文章.但MS的解释完全不令人满意(它没有解释警告的原因),而且他们的解决方案是不可接受的 - 他们说我应该直截了当generic_error.
问题是间接地来自多个虚拟继承std::exception.编译器因此而感到困惑,但忘了告诉你原因.: - /
James McNellis是对的:编译器承诺会提到一种类型,但事实并非如此.尝试没有template:
#include <stdexcept>
class Base: virtual public std::exception {};
class Derv: public Base, virtual public std::exception {};
int main()
{
try {
throw Derv();
} catch (const Base &) {
return 2;
} catch (...) {
return 1;
}
}
Run Code Online (Sandbox Code Playgroud)
使用4级警告进行编译时,这仅仅表示:
警告C4673:投掷'Derv'将不会在捕获站点考虑以下类型
我看到了警告的价值.但在这种情况下,显然4级是错误的.由于所有工作都按预期工作,你可以让编译器沉默:
#pragma warning(disable: 4673)
Run Code Online (Sandbox Code Playgroud)
我想你可以将这个案例作为一个错误报告给微软.编译器应说明类型和问题所在.
| 归档时间: |
|
| 查看次数: |
545 次 |
| 最近记录: |