Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Deriving from std::exception in a library: Does a headers-only solution work for catching exceptions?

Tags:

c++

std

dll

In our cross-platform Open Source library we derive from std::exception in order to define custom exceptions that can be caught in library-code as well as user-code. I saw that this is actually a recommended procedure, but in Visual Studio 2015 (or rather, the accompanying new MSVC version?) a warning is thrown in the implementation class ( warning C4275 ) - see also here: How to dllexport a class derived from std::runtime_error?

Of course we could just ignore the error, but this seems wrong to me.

The reason for the appearance of the warning, as compared to older Visual Studio versions, seems to be that std::exception used to be exported in older MSVC version but meanwhile is not exported anymore. In either case, I feel like it was never "the right way" to go on about this in the form of compiling it into the library.

From what I read in the answers, a better way to do this is to "inline" the class, since exporting the base class (std::exception) may lead to more complications. If I understand correctly, "inlining" here means not using the "inline" keyword but moving the definition into the header and to not export it. Is that even correct?

Assuming this is what is meant: My question is if the compiled library that throws the exceptions, which are definied in one of its headers, will allow to catch the exceptions correctly in the executable linking this library dynamically. But what if the compilers are different? The runtime type information (RTTI) seems relevant here, so is this guaranteed to work in said way even when using different compiler versions or even different compilers? If this does not work, how to solve this in the "right" way?

like image 630
Ident Avatar asked Aug 14 '15 22:08

Ident


1 Answers

Quoting from the Microsoft Connect issue (webarchive) in the post linked in the question;

... putting STL types in your DLL's interface forces you to play by the STL's rules (specifically, you can't mix different major versions of VC, and your IDL settings must match). However, there is a workaround. C4251 is essentially noise and can be silenced...

Mixing compiler versions and options could (and probably will at some point) cause problems and unpredictable behavior of the application. So, there are no guarantees it will work, quiet possibly the opposite, it won't work.

When using the inline technique mentioned above (i.e. a header only implementation) and making sure that the settings and compilers are consistent across the projects allows for a work around given the constraints of the dll exports.

Given that it is an open source project, it can easily be built for the clients environment, so any of the techniques mentioned should be suitable because the client will be able to build the code given their compiler and options they desire.

like image 146
Niall Avatar answered Oct 13 '22 07:10

Niall