Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to catch exception thrown while initializing a static member

I have a class with a static member:

class MyClass
{
public:
    static const SomeOtherClass myVariable;
};

Which I initialize in the CPP file like so:

const SomeOtherClass MyClass::myVariable(SomeFunction());

The problem is, SomeFunction() reads a value from the registry. If that registry key doesn't exist, it throws an exception. This causes my program to explode without giving the user any useful output... is there some way I can catch the exception so I can log it?

like image 874
rmeador Avatar asked Feb 24 '10 22:02

rmeador


People also ask

Which exception is thrown when Java tries to initialize a static variable?

Class ExceptionInInitializerError. Signals that an unexpected exception has occurred in a static initializer. An ExceptionInInitializerError is thrown to indicate that an exception occurred during evaluation of a static initializer or the initializer for a static variable.

What happens if exception occurs in static block?

Throwing exceptions in static block Herefore, if you throw an exception using the throw keyword in a static block you must wrap it within try-catch blocks else a compile time error will be generated.

Can static method throw exception?

A static block can throw only a RunTimeException, or there should be a try and catch block to catch a checked exception. A static block occurs when a class is loaded by a class loader.

How do you initialize a static member?

We can put static members (Functions or Variables) in C++ classes. For the static variables, we have to initialize them after defining the class. To initialize we have to use the class name then scope resolution operator (::), then the variable name. Now we can assign some value.


1 Answers

I don't like static data members much, the problem of initialization being foremost.

Whenever I have to do significant processing, I cheat and use a local static instead:

class MyClass
{
public:
    static const SomeOtherClass& myVariable();
};

const SomeOtherClass& MyClass::myVariable()
{
  static const SomeOtherClass MyVariable(someOtherFunction());
  return MyVariable;
}

This way, the exception will be throw only on first use, and yet the object will be const.

This is quite a powerful idiom to delay execution. It had a little overhead (basically the compiler checks a flag each time it enters the method), but better worry about correctness first ;)

If this is called from multiple threads:

  • if your compiler handles it, fine
  • if your compiler does not, you may be able to use local thread storage (it's const anyway)
  • you could use boost::once in the Boost.Threads library
  • since it's const, you may not care if it's initialized multiple times, unless someOtherFunction does not support parallel execution (beware of resources)

Guideline: only use static or global variables instantiation for simple objects (that cannot throw), otherwise use local static variables to delay execution until you can catch the resulting exceptions.

like image 180
Matthieu M. Avatar answered Sep 27 '22 19:09

Matthieu M.