Search code examples
c++visual-c++declspec

Using __declspec(nothrow) on functions that return references


I'd like to apply __declspec(nothrow) on some of my member functions that return object references. For example, I'd like to add it to this function (in MyClass.h):

CMyClass& operator= ( IN UInt32 nValue )
{
    return ( SetValue ( nValue ) );
};

The VC++ documentation says that I need to add it after the return type of the function like so:

return-type __declspec(nothrow) [call-convention] function-name ([argument-list])

If I follow this, most of my functions work fine with __declspec(nothrow). However, when I do that for the above member function (or any others that return a CMyClass&), I get compile errors:

error C2059: syntax error : '__declspec(nothrow)'

I can put it in front of the return type and it compiles then but the documentation also says that if a __declspec() is placed in the wrong place, the compiler may ignore it without warning or error.

What's the right way of using __declspec(nothrow)?


Solution

  • I believe (but am not 100% certain) the correct syntax is:

    CMyClass __declspec(nothrow) & operator= ( IN UInt32 nValue )
    

    It seems that the compiler follows the same rule for function declarations as it does for simple declarations, and the & (or *) goes after the declspec. This matches some of the MSDN documentation.

    The __declspec keywords should be placed at the beginning of a simple declaration. The compiler ignores, without warning, any __declspec keywords placed after * or & and in front of the variable identifier in a declaration.

    As others have pointed out, though, this is something of a waste of time. throw() doesn't have the same odd parsing issues, and the documentation specifically states that it is equivalent.

    Given the following preprocessor directive, the three function declarations below are equivalent:

    #define WINAPI __declspec(nothrow) __stdcall

    void WINAPI f1();
    void __declspec(nothrow) __stdcall f2();
    void __stdcall f3() throw();