This chapter covers some very basic concepts needed to understand OpenMS code. It describes OpenMS primitive types, namespaces, exceptions and important preprocessor macros. The classes described in this section can be found in the CONCEPT folder.
OpenMS has its own names for the C++ primitive types. The integer types of OpenMS are Int (int) and UInt (unsigned int). For floating point numbers, no such names exist and the primitives float and double should be used.
These and more types are defined in OpenMS/CONCEPT/Types.h. The typeAsString() function can be used to find out the actual type of an object, e.g. if typedefs are used.
The main classes of OpenMS are implemented in the namespace OpenMS. There are several sub-namespaces to the OpenMS namespace. The most important ones are:
There are several more namespaces. For a detailed description have a look at the class documentation.
All exceptions are defined in the namespace OpenMS::Exception. The Base class for all OpenMS exceptions is Base. This base class provides three members for storing the source file, the line number and the function name where the exception occurred. All derived exceptions provide a constructor that takes at least these arguments. The following code snippet shows the handling of an index overflow:
Note the first three arguments given to the constructor: __FILE__ and __LINE__ are built-in preprocessor macros that hold the file name and the line number. __PRETTY_FUNCTION__ is replaced by the GNU g++ compiler with the demangled name of the current function (including the class name and argument types). For other compilers we define it as "<unknown>". For an index overflow exception, there are two further arguments: the invalid index and the maximum allowed index.
The file name, line number and function name are very useful in debugging. However, OpenMS also implements its own exception handler which allows to turn each uncaught exception into a segmentation fault. With gcc this mechanism allows developers to trace the source of an exception with a debugger more effectively. To use this feature, set the environment variable OPENMS_DUMP_CORE. For Visual Studio you should set a breakpoint in GlobalExceptionHandler::newHandler() in Exception.cpp, otherwise you might loose the stacktrace to pinpoint the initial exception.
In order to enforce algorithmic invariants, the two preprocessor macros OPENMS_PRECONDITION and OPENMS_POSTCONDITION are provided. These macros are enabled only if debug info is enabled and optimization is disabled in cmake. Otherwise they are removed by the preprocessor, so they won't cost any performance.
The macros throw Exception::Precondition or Exception::Postcondition respectively if the condition fails. The example from section Exception handling in OpenMS could have been implemented like that:
OpenMS / TOPP release 2.3.0 | Documentation generated on Tue Jan 9 2018 18:22:05 using doxygen 1.8.13 |