-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add library versioning using inline namespaces #1394
Comments
I am not sure how exactly to approach this issue. Will this break existing code? Will two such versioned libraries be able to co-exist? |
I'm interested in this approach, but I'm very curious if anyone knows of a project that successfully uses this approach. For example, libc++ uses this approach to avoid its symbols getting mixed up with libstdc++ (in case you link two libs together that were built against a different STL). They add an inline "__1" namespace, but I'll note that there's never been a __2. More specifically: I'd love to know if any project uses this approach, has actually ever incremented the number -- and, most importantly, is happy with how it has worked out. |
Maybe related: #813. |
Usage of inline namespaces does seem to be low, but I'd risk a guess this is due to people not being familiar with them. I haven't heard of any problems with them. Applying them would be quite simple. Just change all The results would be as follows:
A short introduction to inline namespaces is here: https://foonathan.net/blog/2018/11/22/inline-namespaces.html
I will try to prepare a PR for this. |
Hello, I would like to know which symbol causes the crash in the first place, was it a subtle API breaking change? ODR violation caused by an API compatible but ABI breaking one? I'm supporting the idea of having a single inline namespace for major versions (this is what I've always seen in libraries, e.g. ranges-v3, libcxx). I'm skeptical about having one namespace for each version (minor and patch included). But for your specific use-case, you want to have ABI-related inline namespaces as mentioned in the blog post you linked. I would rather see something like: namespace nlohmann {
inline namespace v3 {
inline namespace abi_v2 {
class stuff {};
}
}
} I've never used ABI inline namespaces though, you should take it with a grain of salt |
The crash was in simple json.dump(). There was no API incompatibility I believe - pure ABI break. As for introducing two inline namespaces (one for API changes, one for ABI changes) I'm not sure it's needed. It would be difficult to track ABI changes. Using full release version for namespace name is the simplest solution in this case.
But personally I would keep just the "v3_3_0" namespace. |
One of the initial purposes of inline namespaces is to allow users to explicitly choose an old behavior when a new major version is introduced: // imagine v4 removed the deprecated stream operations
nlohmann::v3::json j;
std::istream& s = /*...*/;
s >> j; With your proposed change, this is not possible anymore, since there is a single namespace that is bumped on every release (major, minor and patch). Having the two inline namespaces solves that, As for the always-inline one, whether it is |
That being said, I wonder why |
I'd like to avoid having an ABI inline namespace to be honest |
As the library is already quite large and we only have limited resources, I would like to avoid having a single header with multiple versions of the library in it. I'm not sure how to proceed here. |
My proposal is to have just one version in the header. If anyone would want to use different versions of json API in different places of his code he could always do this: // a.cpp
#include <nlohmann/json_2.0/json.hpp>
...
// b.cpp
#include <nlohmann/json_3.0/json.hpp>
... I think the only argument against my idea is that, as theodelrieu said, it should be responsibility of a third-party library to hide any symbols it doesn't need to expose publicly. |
If more libs would use inline namespace in this way then it would be much simpler to resolve such conflicts, so I agree with this idea. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Is this implemented? It says in the changelog but I can't find the associated PR or code. |
It was not implemented. The issue is mentioned in the generated ChangeLog, because it was closed since the previous version. |
I'd like to see this too. Ironically, the fact that it is so easy to integrate this library into your project via copy paste, is exactly what makes it more likely that you'll end up with conflicting versions. |
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. |
Using two versions of this library in the same project causes segfaults. This is expected, but could be avoided by using inline namespaces for library versioning.
For example Google Benchmark (from v2 branch) uses this library in version 3.0.1, my program uses version 3.3.0. This causes crashes.
A solution would be to wrap all code with version specific namespaces to disambiguate them, like this:
The text was updated successfully, but these errors were encountered: