Re: EH & Optimization
"Staffan Langin" wrote:
[...] I though we were discussing whether an compiler
could perform optimizations based on the exception
specification, which I think it can as long as the
functions it invokes DON'T throws any exceptions different
from its own exception specification. I particular, if a
function with and empty exception specification only
invokes functions with an empty exception specification,
the compiler can discard the enforcement of the exception
specification aswell as the code/data needed to unwind the
function.
This is exactly what I'm talking about. It is so intuitive
to think about `throw()' this way, that compilers started to
implement it according to developers' expectations. However,
according to the Standard, empty exception specification
doesn't differ from non-empty one. In any case compiler must
generate a code that enforces exception policy (i.e., if
something unspecified is thrown, then call
`std::unexpected').
MSDN explains this issue, too:
"Exception Specifications"
http://msdn2.microsoft.com/en-us/library/wfa0edys(vs.80).aspx
<quote>
Visual C++ departs from the ANSI Standard in its
implementation of exception specifications. The following
table summarizes the Visual C++ implementation of exception
specifications:
[...]
throw() - The function does not throw an exception. However,
if an exception is thrown out of a function marked throw(),
the Visual C++ compiler will not call `unexpected'. If a
function is marked with throw(), the Visual C++ compiler
will assume that the function does not throw C++ exceptions
and generated code accordingly.
</quote>
[...] The real difference, if I understand it correctly,
is that the enforcement is performed at compile-time for
__declspec(nothrow) but at run-time for throw().
No, there is no any difference between `__declspec(nothrow)'
and `throw()' in VC++2005. From the MSDN link above:
<quote>
An exception specification with an empty throw, as in
void MyFunction(int i) throw();
tells the compiler that the function does not throw any
exceptions. It is the equivalent to using
__declspec(nothrow).
</quote>
Many developers prefer `__declspec(nothrow)' in order to
avoid confusion with `throw()', since someone who reads the
code later may interpret `throw()' according to the Standard
(as opposite to what compiler really generates).
You could try "#pragma optimize("y", on)" for `Context'
constructor. However, I think you already have
optimization switches which imply /Oy.
Disabling optimization is unfortunately out of the
question, since the SEH prolog/epilog would still be
emitted aswell as a lot of unoptimized code.
Actually, "#pragma optimize("y", on)" will enable /Oy
optimization if it is not already enabled. It is equivalent
to /Oy switch (suppress creation of frame pointers on the
call stack).
Alex