2

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)?

xxbbcc
  • 16,930
  • 5
  • 50
  • 83
  • 1
    Why not use the standard-compliant `throw()` marking? – Ben Voigt Feb 06 '12 at 23:00
  • 2
    This is a pretty pointless exercise. The MSVC compiler allows *nothrow* declarations but is part of a group of Real Compiler Implementations that treat the declaration as bs. They got more credit in C++11, exception specifications are deprecated. The new keyword is *noexcept*. Don't bother. – Hans Passant Feb 07 '12 at 00:02
  • 1
    Well, neither throw() nor noexcept works in VC++, while __declspec(nothrow) does. – xxbbcc Feb 07 '12 at 01:39
  • 3
    @Hans Passant: MSVC doesn't completely ignore empty `throw()` specifier, it just implements it in non-standard way. In MSVC `throw()` allows the compiler to omit stack unwinding code, which is similar to `noexcept`. And according to my tests `throw()` and `__declspec(nothrow)` are identical. – Timo Feb 10 '12 at 03:55

1 Answers1

3

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();

Derek Park
  • 45,824
  • 15
  • 58
  • 76
  • thanks for the answer, I'll try it this way. I read the docs but I guess that part you quoted didn't stick. I'll see if I get equivalent assembler output for `throw()` and `_declspec(nothrow)`. – xxbbcc Feb 10 '12 at 17:08