api: make a 2-level namespace scheme #4567
Open
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
TL;DR: In main, change the enclosing namespace from
OpenImageIO_v3_1
to a 2-level scheme:OpenImageIO::v3_1
. This can't be backported to the current release for obvious ABI cmopatibility reasons; it is a forward-looking change only.More ponderous explanation follows:
We have for some time had a single namespace that incorporates the version, defaulting to
OpenImageIO_v3_0
in the current release, for example. A namespace alias,OIIO
, always aliases the current namespace, so client applications can just sayOIIO::foo
without needing to change source code for every minor release (let alone if a build-time option sets up a custom namespace).By bumping the namespace for every minor release, we use the symbol names themselves to enforce a rigid ABI compatibility test, so you can't accidentally compile against one minor release and link against an older minor release. This gives us the freedom to break the ABI (link compatibility) for each minor release, without subtle user errors. (Doing it wrong makes a total failure to link, which is hard to miss.)
But being able to introduce ABI changes annually by changing the enclosing namespace comes at the cost of a complete ABI compatibility break with every minor release. Even classes or functions that haven't changed at all will be incompatible by virtue of their changed symbol names.
This is an unfortunate limitation, and in an ideal world, we would like downstream users to be able to upgrade to a newer minor release more painlessly, and confident that they could even relink or perhaps compile with a request to use an old ABI.
I haven't fully worked out all the details, or even if this is going to be worth the trouble, but I think that a change we can introduce now that will allow more flexibiity in the future is to switch to a 2-level namespace scheme, for example,
OpenImageIO::v3_1
instead of the currentOpenImageIO_v3_1
.The reason this might be helpful in the future is that we can use "inline" namespaces that default to finding things that are in, say, OpenImageIO::v3_2 without needing to specify it explicitly, while giving the ability to explicitly give an alternate inner versioned namespace. I haven't implemented that part here, it's reserved for future expansion (though I have experimented with it, it does work, but I want to discuss separately whether or not to actually do it).