I have a function that can be reduced to this:
void f() {
static MyObject o("hello");
DoSomethingWith(o);
}
This function is called across a C API boundary, so like a good boy, I use try
to catch any exceptions that are thrown before they cross the boundary and screw things up:
void f() {
try {
static MyObject o("hello");
DoSomethingWith(o);
} catch (const MyObjectException& e) {
Message("Constructor of o failed");
}
}
This function is called the first time and I get the message "Constructor of o failed"
. However, later, the function is called again, and I get the message again. I get the message as many times as f
is called. I am using Visual C++ so this tells me what MSVC++ does, but not what should be done.
My question is, what should happen when the constructor of a static
function variable terminates unusually (by throw
ing, a longjmp
out of the constructor, termination of the thread that it's in, etc)? Also what should happen with any other static
variables declared before and after it? I would appreciate any relevant quotes from the standard as well.
Redesign your program. Static variables will be attempted to be initialized until the initialization succeeds. If that pattern doesn't fit, you should find a better way to express your goal. Perhaps a static
unique_ptr
that you populate in a controlled environment? If you have a resource that you cannot reliably construct, you have to either relegate the construction into some other context where you can handle the error, or make your function depend only optionally on the resource (e.g. via a null pointer).Section 6.7 (
[stmt.dcl]
) of the C++11 standard states thatSo the initialization of
o
will be tried again if it exits by throwing an exception.I think the same applies to any kind of abnormal exit from the initialization, though it's not explicitly stated. Brb, looking for more quotes.Since I couldn't find anything related, I opened a follow-up question.
§3.6.3 [basic.start.term]
§3.7.2 [basic.stc.thread]