Travis Vitek wrote:
Martin Sebor wrote:

Farid Zaripov wrote:

I've just tried to declare and define __rw_once with throw(...)
exception specification and compiler doesn't issues warning in
that case.

Yes, but the documentation linked to explicitly says...

  Explicit exception specifications are not allowed on C functions.
  [http://msdn2.microsoft.com/en-us/library/wfa0edys(VS.80).aspx]

Yet they describe the behavior of functions, including those
with C linkage, in terms of explicit exception specification.
How ironic!


I tested, it does compile, and the destructors are getting called as
they should when an explicit throw(...) spec is added to the C linkage
function. That said, I cringe at the thought relying on behavior that is
documented to not work or is not supported.

No kidding!


Maybe when the documentation is referring to C functions it means
functions that are compiled as C source [x.c instead of x.cpp] and not
functions with C linkage?

Who knows... Have you tried it?


Good to know! We still need to decide how to handle this in
the general case (for compilers that behave like MSVC, if
there are any) but we can certainly start using this extension
to silence the MSVC warnings.


Is the goal really to just squelch the warnings? I hope not.

No, not just that (we could simply use #pragma warning to silence
them if that was the only goal).


So back at square one, I have another question. Lets assume a program
will abort() if an exception is thrown through a C function. This
characterization test will fail, and the build framework will probably
set a preprocessor flag _RWSTD_NO_EXTERN_C_EXCEPTIONS. What exactly
would we do to prevent this from being a problem? I can think of two
things.

  1. Add a try/catch block inside every once function definition
     that might throw.
  2. Implement our own pthread_once() type function that has C++
     linkage and use it with all configurations on all platforms.

Both solutions are compatible with all systems, and would eliminate the
warning on MSVC as a side effect. Obviously the first option isn't that
pleasant because there is no _good_ way I can see to communicate a
failure back to the application. Is there something wrong with the
second option?

Good questions.

I suppose the potential overhead would be my biggest concern.
The solution we discussed recently on another list (overloading
pthread_once() for extern "C++" functions) involves dynamically
allocating a small chunk of memory. That's a steep price to pay
for one time initialization.

But we might be solving a non-issue. I'm not sure yet that there
are any one-time initializers in the library that can throw an
exception. So I think we're safe until we've actually found one
that does. Although it surely would be nice to have a robust
solution in place just in case we add an initializer that can
throw in the future.

Btw., there is another alternative: For compilers like MSVC
that ignore the difference between extern "C" and extern "C++"
functions (i.e., where _RWSTD_NO_EXTERN_C_COMPATIBILITY is
#undefined) we can just pass extern "C++" functions to
__rw_once().

Martin

Reply via email to