Hacker News new | ask | show | jobs
by humanrebar 1204 days ago
EDIT: I'm not sure the below answers the question as asked, but it does clarify why A and B probably want to use the same version of boost.

In practice A and B would each have their own namespaces in C++ codebases, but that wouldn't resolve the tension if each wanted a different version of boost. One approach to resolve that tension is to figure out how to have two versions of boost in the same dependency tree. The below is addressing that proposal.

---

Practically, no. You could certainly create a new namespace C++ names: functions, classes, global variables, and so on.

But there are other "names" in C++ that don't respect C++ namespaces: C symbols, included headers, preprocessor names, and library names (as in `-lfoobar` on a link line). You'd need to make up new names for all of these and possibly a few more things to make a full duplicate of a library.

Now, if you managed to do all that, there are still problems to watch out for. For instance, it's common for projects to assume that global or static names in a C++ namespace can be treated as unique process-wide values in a running program. As in, `mynamespace::important_mutex` might guard access to specific hardware, so having a `mynamespace2::important_mutex` also thinking it has the same job would be bad.

And if that wasn't a problem, you still have to think about types that show up in APIs. How will downstream code be written when you have a `boost::string_ref` and a `boost2::string_ref` in the same codebase? Which `string_ref` do you use where? Can you efficiently convert from one to the other as needed? Will that require changing a lot of downstream code?

1 comments

The only sane solution is, for libraries that need wide backward and forward compat, is to only expose abi/api stable types in your interface, but it doesn't. You can use still use boost internally, but make the symbols private and/or in a private namespace.

At the limit a stale interface is a C interface, but it doesn't have to be. GCC std types are fairly stable, and Qt manages a rich interface while maintaining robust ABI compatibility. It is hard work, and not always worth it of course.

Narrowing the interface helps, but the other "interface" is how the linker resolves names to specific addresses to code or data. The example I mention involving mutexes does not require those mutexes show up in public interfaces or necessarily "break" ABI guarantees. The mutexes don't even have to be used by the same source files! I guess you could consider it a library design flaw, but it's basically never mentioned as a design antipattern if it is one.

Note that it's not just mutexes. The same can happen with other kinds of "one per process" resources: memory pools, thread pools, connection pools, caches, registry objects, etc.