[type_traits][general] Best practice for inline namespaces?
I was thinking of adding inline namespace support (ie lib versioning) to type_traits, but what's the best practice for naming the inline namespace? I was thinking of going with some mangled version of BOOST_VERSION which would effectively change the namespace with each release. That feels like it's probably right to me: old versions of any traits would then be archived in boost::tt105600:: or whatever version the change happened. Comments? Thanks, John.
On Sun, Jan 18, 2015 at 6:16 AM, John Maddock
I was thinking of adding inline namespace support (ie lib versioning) to type_traits, but what's the best practice for naming the inline namespace? I was thinking of going with some mangled version of BOOST_VERSION which would effectively change the namespace with each release. That feels like it's probably right to me: old versions of any traits would then be archived in boost::tt105600:: or whatever version the change happened. Comments?
The Google style ( http://google-styleguide.googlecode.com/svn/trunk/cppguide.html) is against inline namespace usage, but I see that in case of multiple versioning this might me interesting to use. Roger
On 1/18/15 8:45 AM, Rogerio dos Santos wrote:
On Sun, Jan 18, 2015 at 6:16 AM, John Maddock
wrote: I was thinking of adding inline namespace support (ie lib versioning) to type_traits, but what's the best practice for naming the inline namespace? I was thinking of going with some mangled version of BOOST_VERSION which would effectively change the namespace with each release. That feels like it's probably right to me: old versions of any traits would then be archived in boost::tt105600:: or whatever version the change happened. Comments?
The Google style ( http://google-styleguide.googlecode.com/svn/trunk/cppguide.html) is against inline namespace usage, but I see that in case of multiple versioning this might me interesting to use.
Roger
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
The google style guide forbids the use of Boost in general with a very few exceptions. Among those is: "The part of Polygon that deals with Voronoi diagram construction and doesn't depend on the rest of Polygon" In view of that, I think it makes little sense for the Boost developers to adhere to the google guidelines, at least until they condescend to admit the Pentagon as well.
On Sunday 18 January 2015 12:16:37 John Maddock wrote:
I was thinking of adding inline namespace support (ie lib versioning) to type_traits, but what's the best practice for naming the inline namespace? I was thinking of going with some mangled version of BOOST_VERSION which would effectively change the namespace with each release. That feels like it's probably right to me: old versions of any traits would then be archived in boost::tt105600:: or whatever version the change happened. Comments?
I think the major point for keeping the old TypeTraits is backward compatibility, i.e. user's code should not require modification. So I think it's better to keep the old implementation as is and use a new namespace for the new one. FWIW, I'm using inline namespaces (or emulation in C++03) in Boost.Log, although I don't inject Boost version. Works quite well in detecting configuration mismatch cases, when user's code is compiled in a mode incompatible with the compiled library. I'm not sure how useful this would be with TypeTraits though, given that the traits are compile-time constructs and ABI compatibility is not an issue.
FWIW, I'm using inline namespaces (or emulation in C++03) in Boost.Log, although I don't inject Boost version. Works quite well in detecting configuration mismatch cases, when user's code is compiled in a mode incompatible with the compiled library. I'm not sure how useful this would be with TypeTraits though, given that the traits are compile-time constructs and ABI compatibility is not an issue.
I think you may have hit the nail on head there: are inline namespaces of any use for header-only code? I can see the logic for mangling the names when you're linking to an external lib, but for something like type_traits we can just as well leave things as they are and use a nested namespace for any "archived" old versions of the code. John.
On Sunday 18 January 2015 17:10:04 John Maddock wrote:
FWIW, I'm using inline namespaces (or emulation in C++03) in Boost.Log, although I don't inject Boost version. Works quite well in detecting configuration mismatch cases, when user's code is compiled in a mode incompatible with the compiled library. I'm not sure how useful this would be with TypeTraits though, given that the traits are compile-time constructs and ABI compatibility is not an issue.
I think you may have hit the nail on head there: are inline namespaces of any use for header-only code?
Yes, they are in general. Things like function, shared_ptr, any, variant are often present in binary interfaces of user's code. Making these component names versioned will make sure that user's ABI wont break if he (accidentally) mix different versions of Boost or different configurations. But that's not the case for libraries like TypeTraits or MPL.
On 19/01/2015 07:07, Andrey Semashev wrote:
On Sunday 18 January 2015 17:10:04 John Maddock wrote:
I think you may have hit the nail on head there: are inline namespaces of any use for header-only code?
Yes, they are in general. Things like function, shared_ptr, any, variant are often present in binary interfaces of user's code. Making these component names versioned will make sure that user's ABI wont break if he (accidentally) mix different versions of Boost or different configurations. But that's not the case for libraries like TypeTraits or MPL.
It depends. Both TypeTraits and MPL can appear in the user's header files to select types for use in user code, including unit-to-unit interfaces which are an inherent ABI boundary. shared_ptr etc are *more* exposed, in that their size and memory layout also forms part of the ABI contract (unlike TypeTraits and MPL, where the internals are less critical), but if there is a chance that the resulting type output of a TT/MPL metafunction can change from one release to the next or for one compilation setting vs. another, then it also becomes potentially ABI breaking. It seems to be a common misconception (http://www.boost.org/development/separate_compilation.html) that header-only libraries are not subject to incompatible ABI issues. That's simply not true, especially when the user is using multiple ABI-affecting settings in their code.
On 20 Jan 2015 at 11:01, Gavin Lambert wrote:
On 19/01/2015 07:07, Andrey Semashev wrote:
On Sunday 18 January 2015 17:10:04 John Maddock wrote:
I think you may have hit the nail on head there: are inline namespaces of any use for header-only code?
Definitely.
Yes, they are in general. Things like function, shared_ptr, any, variant are often present in binary interfaces of user's code. Making these component names versioned will make sure that user's ABI wont break if he (accidentally) mix different versions of Boost or different configurations. But that's not the case for libraries like TypeTraits or MPL.
I would have said the bigger benefit is that ABI *does* break when a version iterates. For example, you *want* a library compiled against Boost v1.54 to not link ever against Boost v1.55. On POSIX where the symbol namespace is global this is a very real concern as without inline namespacing loading libraries with slightly differing Boost dependencies will trample all over one another.
It depends. Both TypeTraits and MPL can appear in the user's header files to select types for use in user code, including unit-to-unit interfaces which are an inherent ABI boundary.
shared_ptr etc are *more* exposed, in that their size and memory layout also forms part of the ABI contract (unlike TypeTraits and MPL, where the internals are less critical), but if there is a chance that the resulting type output of a TT/MPL metafunction can change from one release to the next or for one compilation setting vs. another, then it also becomes potentially ABI breaking.
It seems to be a common misconception (http://www.boost.org/development/separate_compilation.html) that header-only libraries are not subject to incompatible ABI issues. That's simply not true, especially when the user is using multiple ABI-affecting settings in their code.
As BindLib soon to be renamed to something else shows, you can also use inline namespaces to externally select implementations of Thread, Filesystem, Networking and any other internal library dependency. This makes much easier libraries which can link against either the C++ 11 STL or Boost or multiple versions of Boost, all in the same translation unit if needs be. I would very strongly advise that all new Boost libraries should be required to version their API when inline namespace support is available, and that all existing Boost libraries be upgraded as soon as their maintainer can make it happen. Niall -- ned Productions Limited Consulting http://www.nedproductions.biz/ http://ie.linkedin.com/in/nialldouglas/
On 2015-01-18 18:10, John Maddock wrote:
FWIW, I'm using inline namespaces (or emulation in C++03) in Boost.Log, although I don't inject Boost version. Works quite well in detecting configuration mismatch cases, when user's code is compiled in a mode incompatible with the compiled library. I'm not sure how useful this would be with TypeTraits though, given that the traits are compile-time constructs and ABI compatibility is not an issue.
I think you may have hit the nail on head there: are inline namespaces of any use for header-only code? I never really understood their benefits for versioning, but there are other uses in header-only code of course. For instance, I like the ones for user defined literals, see
http://en.cppreference.com/w/cpp/chrono/operator%22%22h Users can pull in these literals into their scope at the granularity of their choice due to nested inline namespaces. Very nice, IMHO.
Le 18/01/15 13:16, John Maddock a écrit :
I was thinking of adding inline namespace support (ie lib versioning) to type_traits, but what's the best practice for naming the inline namespace? I was thinking of going with some mangled version of BOOST_VERSION which would effectively change the namespace with each release. That feels like it's probably right to me: old versions of any traits would then be archived in boost::tt105600:: or whatever version the change happened. Comments?
I'm not for associating the version of Boost to the one of the library. Using inline namespaces in order to versioning has a sense only when you cannot be backward compatible. I would use only the major version. namespace boost { inline namespace type_traits { #if BOOST_TYPE_TRAIT_MAJOR_VERSION=1 inline namespace v1 { .... } #elif BOOST_TYPE_TRAIT_MAJOR_VERSION=2 inline namespace v2 { ... } } } I suppose that you know that inline namespaces emulation via using doesn't support template class specialization, as the user must do the specializations on the original namespace. :( Best, Vicente
On Sunday 18 January 2015 16:36:33 Vicente J. Botet Escriba wrote:
I suppose that you know that inline namespaces emulation via using doesn't support template class specialization, as the user must do the specializations on the original namespace. :(
GCC 3.4 and later has __attribute__((strong)) which allows that. https://gcc.gnu.org/onlinedocs/gcc/Namespace-Association.html#Namespace-Asso...
Le 18/01/15 16:48, Andrey Semashev a écrit :
On Sunday 18 January 2015 16:36:33 Vicente J. Botet Escriba wrote:
I suppose that you know that inline namespaces emulation via using doesn't support template class specialization, as the user must do the specializations on the original namespace. :( GCC 3.4 and later has __attribute__((strong)) which allows that.
https://gcc.gnu.org/onlinedocs/gcc/Namespace-Association.html#Namespace-Asso...
Thanks for the info. Does this work for clang? Vicente
On Sunday 18 January 2015 17:38:11 Vicente J. Botet Escriba wrote:
Le 18/01/15 16:48, Andrey Semashev a écrit :
On Sunday 18 January 2015 16:36:33 Vicente J. Botet Escriba wrote:
I suppose that you know that inline namespaces emulation via using doesn't support template class specialization, as the user must do the specializations on the original namespace. :(
GCC 3.4 and later has __attribute__((strong)) which allows that.
https://gcc.gnu.org/onlinedocs/gcc/Namespace-Association.html#Namespace-As sociation Thanks for the info. Does this work for clang?
No, I don't think it does.
participants (9)
-
Andrey Semashev
-
Gavin Lambert
-
John Maddock
-
John Maddock
-
Niall Douglas
-
Oleg Grunin
-
Rogerio dos Santos
-
Roland Bock
-
Vicente J. Botet Escriba