On 10 Feb 2015 at 1:07, Nevin Liber wrote:
Unless you can always build everything from source (as opposed to linking against libraries built by others), this becomes a nightmare when trying to avoid ODR violations.
It would be a very poor implementation that had that problem Nevin.
Parts of Boost *already* have that problem.
Suppose I'm using Boost.Fusion, and I need a 50 element Fusion vector. If I want to change that, the documentation < http://www.boost.org/doc/libs/1_57_0/libs/fusion/doc/html/fusion/container/vector.html> says:
You may define the preprocessor constant FUSION_MAX_VECTOR_SIZE before including any Fusion header to change the default. Example:
#define FUSION_MAX_VECTOR_SIZE 20
So, without rebuilding the entire world, how do I increase the maximum size of a Fusion vector without an ODR violation??
This is a huge problem with global flags.
[Note: I am not criticizing Boost.Fusion here, as they really didn't have a choice in a pre-variadic template world.]
You'd almost certainly use namespaces or template parameters to make symbol unique the two implementations.
Again, how do you do this if you are using compile time switches? Please post some sample code showing the technique you envision for users.
Assuming you actually want an answer here and are not baiting for the sake of it as usual ... Your example above requires much more than a useful ABI break as was originally being discussed. A compile time selectable option for whether thread safety is there or not can be easily encoded into a boolean at the end of every template parameter, or via a compile time thunk to two internal implementation namespaces. If you have C++ 11, you can even let code change FUSION_MAX_VECTOR_SIZE during compilation and get multiple Fusions in the same translation unit if Fusion were built on top of my BindLib framework. Each Fusion would not work with any other however without additional bridge code. If you want a taste of the macro programming involved for multi-ABI-in-the-same-TU use of BindLib, check out https://github.com/BoostGSoC13/boost.afio/blob/clang_reformat_test/inc lude/boost/afio/config.hpp. However what you ask for is the ability to have the compiler regenerate code on the basis of a compile time option change. One approach is to type erase code which needs to be regenerated such that it can pass through precompiled parts, and thunk out via a virtual function back into just in time compiler assembled functionality. It's a lot of hassle, but std::function and std::bind make it work. Past that though, sans C++ Modules or performing magic via dynamic JIT recompilation of clang ASTs, I don't believe it is straightforward no. That's a language limitation of statically compiled languages with the evolution of toolset we currently have. You might find my 2014 C++ Now paper of interest here, I exactly envisaged a future C++ toolset which could do exactly as you want. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/