8

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?

Community
  • 1
  • 1
Ident
  • 1,184
  • 11
  • 25
  • As I understand the issue, there are two options. (1) Require the same toolchain across the entire application. Then you can ignore and silence C4275 and C4251. (2) Allow different toolchains and export only C-compatible interfaces (no classes with virtual functions, exceptions, inlines or any other newfangled bijouterie across module borders). Anything in between is asking for trouble. I might be mistaken, but I always go with option 1 and I haven't seen any sign of problems yet. – n. m. could be an AI Sep 06 '15 at 20:36
  • That's a good point but you wouldn't want to know how many times we ecnountered one of the following: users combining precompiled binaries of older compiler versions with a newer compiler creating the executable and complaining if it doesnt work, or complain if we dont provide precompiled binaries (oh no, having to compile a library on your own!!!), or people mixing debug and release runtimes forcefully (the horrors) and blaming us, or people compiling a library on one computer with one toolset and linking it to an executable on another with another toolset, etc etc etc. – Ident Sep 07 '15 at 09:16
  • We should probably indeed add some kind of compile-time error or similar preventing from linking between mismatching toolsets – Ident Sep 07 '15 at 09:18
  • Bijouterie. I learned a new word today. – Bondolin Apr 01 '16 at 13:29

1 Answers1

8

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.

Niall
  • 30,036
  • 10
  • 99
  • 142
  • If I get you right you are saying that if we somehow restrict mixing of compiler versions we can either use the dll exported exception we have now or move it to a header-only implementation and it should always work in both cases (i dont see the benefit of moving it to the header though then),correct? – Ident Sep 07 '15 at 09:27
  • @Ident. Correct. Both would work. I've slowly become more keen on the inline only option, just because it gives fewer warnings etc. and offers a little more flexibility in our environment(s) - but frankly there is little to nothing between the two - it is an implementation decision. – Niall Sep 07 '15 at 10:09