警告C4290:忽略C ++异常规范,除非指示函数不是__declspec(nothrow)

时间:2014-03-19 10:21:40

标签: visual-c++

在VS 2008中编译我的vc ++代码时产生的这个特殊警告让我感到困扰了一段时间。通过SO和microsoft论坛中的相关帖子进行此警告时,建议使用编译指示警告禁用警告,但是有没有办法在没有警告实用程序的情况下解决此问题?

class CBLockException : public CBException
{
public:
    // Constructor
    CBLockException();
    CBLockException(const char *tag);
    CBLockException(const char *func, const char *tag, const char *msg = NULL);
};


class CLASS_DECL_BASEOBJECTS CBLock : public CBObject
{
public:

    enum Locktype { READLOCK, WRITELOCK };

    CBLock() throw (CBLockException*);   // C4290
    virtual ~CBLock();

    void Lock(Locktype lockType = WRITELOCK);
    void Unlock(Locktype lockType = WRITELOCK);

private:
    class LockImplementation;

    LockImplementation *lockImp;
};


class CBLock::LockImplementation
{

public:
    LockImplementation() throw (CBLockException*);  //C4290
    ~LockImplementation();

    CRITICAL_SECTION csExclusive;                      
    CRITICAL_SECTION csReader;                         
    HANDLE           hevReadDone;                        
    int              cReader;                               
};

2 个答案:

答案 0 :(得分:0)

转到项目属性页 - >配置属性 - > C / C ++ - >高级 - >禁用特定警告 - >修改

输入以分号分隔的警告代码(在您的情况下为4290,不带前导“C”)

来源:http://msdn.microsoft.com/en-us/library/jj715718.aspx

答案 1 :(得分:0)

  

但是有没有办法在没有警告的情况下解决这个问题呢?

是。删除throw规范。它没有做你认为它做的事情。相反,它几乎没用。

具体来说,写作:

CBLock() throw (CBLockException*);
…
CBLock::CBLock() { /* … */ }

基本上等同于

CBLock();
…
CBLock::CBLock() {
    try {
        /* … */
    } catch(CBLockException*&) { // Yes, like this! Stop throwing exceptions by pointer, please!
        throw;
    } catch(...) {
        throw std::bad_exception();
    }
}

(实际上,使用构造函数,它将等同于函数try块,但我不想让它与另一个C ++ wart进一步复杂化)

特别注意它确实实际检查该块没有抛出任何其他类型的异常。它唯一能做的就是将任何其他异常转换为完全无用的std::bad_exception,在此过程中抛弃任何有用的信息。

建议的解决方法是将任何throw声明转换为文档注释!

另请注意,这甚至适用于throw()规范。唯一有用的是C ++ 11中引入的nothrow规范,它实际上检查函数不会抛出任何C ++异常,而且它是早期MSC ++特定的__declspec(nothrow)等价物。