A possible date for dropping c++03 support
-----Original Message----- From: Glen Fernandes
Sent: Tuesday, August 28, 2018 1:25 AM To: mike.dev@gmx.de Subject: Re: [boost] A possible date for dropping c++03 support On Mon, Aug 27, 2018 at 1:10 PM Mike Dev
wrote: Conditionally using a c++11/14/17 feature is (usually) not the problem although there are sometimes pitfalls as Peter mentioned. However, it also has limited utility. E.g. it doesn't make sense to simplify a function implementation using c++11 features like auto, range based for, decltype, constexpr instead of TMP, if you have to maintain the c++03 code path as well. In principle, you could conditionally get rid of some boost dependencies in c++11 mode, but again at the cost of maintaining two different code paths (as boost types often have slightly different semantics from c++11). So why do it? And you still can't deprecate the dependency itself because it is still needed in c++03 mode.
Why do it? I do it when it provides some benefit to the users:
e.g. If alternative implementation using C++14 constexpr results in faster compilation for users. If supporting C++11 move semantics results in better performance for the users. If supporting C++11 variadic templates results in a more flexible interface for the users.
i.e. If I'm the maintainer, and I'm happy to have that burden of maintenance, why does anyone else care that I support C++03/C++11/C++14 users, in addition to C++17 users?
Yes, these are the high value proposition cases, that you mention.
There's also no dependency to the user is there?. e.g. If a library obtain std::addressof from <memory> in C++11 mode and doesn't source it from Boost.Core, to the user, the library doesn't depend on Boost.Core.
So except for cases with a very high value proposition (move semantics, simplified api, c++11 only functionality) or simple annotations (noexcept, override) using c++11 features *conditionally* is usually not all that beneficial. My hope here is that at some point, those boost libraries will finally start to use c++11 features *unconditionally* in order to simplify things - not add even more complexity in the form of conditional compilation.
Simplify things for which party? Are you worried about users or Boost library authors/maintainers? I don't see how users are inconvenienced unless the user wants some feature only available in later C++ modes that the library maintainer refuses to implement.
Glen
There are (at least) three problems: 1) Not all dependencies are private. If a library e.g. uses boost::function in its interface (in particular if it returns one) the user is also directly affected by changes to that dependency. 2) As you know, the c++ compilation model is incredibly leaky, meaning transitive dependencies are not hidden from the user. E.g. if you are using boost core in your header and I include it, I do get all the symbols (including macros) in my TU too. Boost has (usually) very good hygiene, so the main problems here are usually compilation times, sometimes code size and tools (code highlighting, static analysis, refactoring etc.) that either get slower or totally break e.g. because they don't have a perfect emulation of the compilation environment and don't know which code paths are the currently active ones or are just not able to understand all the TMP. 3) Not every library in boost is as well maintained as yours and I as a user prefer "cleaner / simpler" libraries because they a) tend to have fewer bugs, b) I can more easily modify things myself if necessary, c) the easier the life of the maintainer, the more likely he has time to add new functionalities. Finally, if boost can deprecate and at some point even remove some libraries, then their maintainers (in particular the CMT) can focus their time on different projects. Btw.: In case this was not clear: I'm not a boost contributor myself and for some time now, we (as in our company) are actively trying to avoid boost dependencies for various reasons that have more to do with boost-internal stuff and the boost eco system than with e.g. inconvenient interfaces. So yes, at least some end-users do really care about the internals of boost. But admittedly, I mostly work on (semi-) embedded projects where we have to compile (and on rare occasion even modify) boost ourselves - not sure how common that is. Best Mike
On Mon, Aug 27, 2018 at 11:56 PM Mike Dev wrote:
There are (at least) three problems:
1) Not all dependencies are private. If a library e.g. uses boost::function in its interface (in particular if it returns one) the user is also directly affected by changes to that dependency.
If the user isn't using the interfaces of library Boost.X which use boost::function, but instead using the interfaces of library Boost.X that accept std::function, when boost::function changes, yes, library Boost.X is affected, but in what way is this painful for you as a user?
2) As you know, the c++ compilation model is incredibly leaky, meaning transitive dependencies are not hidden from the user. E.g. if you are using boost core in your header and I include it, I do get all the symbols (including macros) in my TU too. Boost has (usually) very good hygiene, so the main problems here are usually compilation times, [...]
In my example for this, if library Boost.Y only conditionally includes Boost.Core for boost::addressof, (e.g. only if BOOST_NO_CXX11_ADDRESSOF is defined) you won't get anything from Boost.Core, because for you, there will be no #include of anything from Boost.Core. For you, library Boost.Y would only be including <memory>.
3) Not every library in boost is as well maintained as yours and I as a user prefer "cleaner / simpler" libraries because they a) tend to have fewer bugs, b) I can more easily modify things myself if necessary, c) the easier the life of the maintainer, the more likely he has time to add new functionalities. Finally, if boost can deprecate and at some point even remove some libraries, then their maintainers (in particular the CMT) can focus their time on different projects.
Here's what I was trying to understand with my original question: What will change if we (Boost) make that announcement tomorrow? It's still up to the library maintainer. If Boost.Z maintainer still wants to support C++03 because of users that they care about, they will still reject your desire for it to use C++11 features unconditionally even if it makes the implementation internals of Boost.Z easier to read. (Which CMT maintainers are struggling today, because the library they are maintaining has C++03 support? The CMT is voluntary, and they should be encouraged to focus their time on projects they want to work on in Boost, and let users who care about the unsupported libraries to step up and volunteer to maintain them.) Glen
On Tue, 28 Aug 2018 at 14:11, Glen Fernandes via Boost < boost@lists.boost.org> wrote:
(Which CMT maintainers are struggling today, because the library they are maintaining has C++03 support? The CMT is voluntary, and they should be encouraged to focus their time on projects they want to work on in Boost, and let users who care about the unsupported libraries to step up and volunteer to maintain them.)
They do what is expected of them, kick the can forward, no criticism (even the slightest, thanks) intended. Moving a library, properly, to C++11 is not what they signed up for. degski -- *“If something cannot go on forever, it will stop" - Herbert Stein* *“No, it isn’t truth. Truth isn’t truth" - Rudolph W. L. Giuliani*
-----Original Message----- From: Glen Fernandes
Sent: Tuesday, August 28, 2018 7:11 PM On Mon, Aug 27, 2018 at 11:56 PM Mike Dev wrote:
There are (at least) three problems:
1) Not all dependencies are private. If a library e.g. uses boost::function in its interface (in particular if it returns one) the user is also directly affected by changes to that dependency.
If the user isn't using the interfaces of library Boost.X which use boost::function, but instead using the interfaces of library Boost.X that accept std::function, when boost::function changes, yes, library Boost.X is affected, but in what way is this painful for you as a user?
I was talking about interfaces that only use boost::function instead of std::function. If you are saying, you use the preprocessor to generate only one or the other version of an interface depending on the c++ language version, then this is indeed no real problem for the user, assuming both versions are tested and all parts of the final program are compiled with the same c++ version (which - especially on linux - may or may not be true). Dependency analysis/management tools will probably still think I have a dependency on boost::function though.
2) As you know, the c++ compilation model is incredibly leaky, meaning transitive dependencies are not hidden from the user. E.g. if you are using boost core in your header and I include it, I do get all the symbols (including macros) in my TU too. Boost has (usually) very good hygiene, so the main problems here are usually compilation times, [...]
In my example for this, if library Boost.Y only conditionally includes Boost.Core for boost::addressof, (e.g. only if BOOST_NO_CXX11_ADDRESSOF is defined) you won't get anything from Boost.Core, because for you, there will be no #include of anything from Boost.Core. For you, library Boost.Y would only be including <memory>.
Same answer as above: you are right, if Boost.Y really completely eliminates all direct and indirect dependencies on Boost.Core in c++11 then at least compile times should not be effected. However, I can tell you that this currently not the common case in boost. I checked it some time ago for boost::array and there were at least a dozen (probably dozens - I stopped at some point) libraries that directly or indirectly included boost.array unconditionally. And a quick check shows that boost function is also unconditionally included in at least a few libraries. Unfortunately, boostdep is afaik not preprocessor aware - that would make those kinds of analysis much easier.
3) Not every library in boost is as well maintained as yours and I as a user prefer "cleaner / simpler" libraries because they a) tend to have fewer bugs, b) I can more easily modify things myself if necessary, c) the easier the life of the maintainer, the more likely he has time to add new functionalities. Finally, if boost can deprecate and at some point even remove some libraries, then their maintainers (in particular the CMT) can focus their time on different projects.
Here's what I was trying to understand with my original question: What will change if we (Boost) make that announcement tomorrow? It's still up to the library maintainer. If Boost.Z maintainer still wants to support C++03 because of users that they care about, they will still reject your desire for it to use C++11 features unconditionally even if it makes the implementation internals of Boost.Z easier to read.
Absolutely, it still depends on the individual library maintainer. However, if boost would indeed make such announcement that alone would be an indicator that at least some maintainers want to make that change, but probably didn't dare to do it alone. If there is no interest from the side of the c++03 library maintainers, then this announcement will never happen. The big question is, what happens if most, but not all maintainers are for it and then actually migrate to c++11. Would the remaining libraries internalize all their former dependencies to stay c++03 compatible? Best Mike
participants (3)
-
degski
-
Glen Fernandes
-
Mike Dev