It's nice to have stack traces, but we can't realistically make ThrowException depend on Stacktrace, for several reasons. First and least, dependency cycles. Second, Stacktrace is not header-only, so all header-only libraries that throw exceptions will acquire a compiled dependency, which is a massive pain.
And third, even for compiled libraries, the way Stacktrace uses separate library per backend makes it hard to express the dependency in b2 or CMake, because you have no idea what target your library needs to link to. Perhaps StackTrace could be split into a capture-only component that has
On 15/02/2022 13:50, Peter Dimov wrote: the properties you desire and a formatting component for the rest? Although I suspect platform differences for stack capture would likely make having it be header-only too impractical. Still, I usually regard header-only as a misfeature anyway. What's probably a more practical solution might be to have potential throw sites declare a context object on their stack. Any Boost-aware throw that occurs while these objects are on the stack would capture whatever additional information is requested by the context objects that are still in scope at the time. This might be a stack trace, a source location, a plain string, or any other context info (e.g. method parameters) that seems useful. (This fixes the dependency problem because it could be StackTrace, or a third library dependent on both, that provides the stack-tracing-capture context class. And one instance of this could be declared at the top of each thread to cause stack tracing on any Boost-aware exception thrown on the thread.) One possible downside is that this is unlikely to be zero-cost in the successful path, unless you can avoid making copies of the data unless an exception is actually thrown, which might limit what can be captured (e.g. capturing calculated rvalues may be harder, though possibly a lambda may help hide that).
But there's more to it. If you follow a straightforward style in which you immediately throw on error, capturing stack traces on throw works well. But if your library is written to use error codes internally, so that it can expose a dual API to the user, that is, to be usable with either exceptions or error codes, things are not so rosy. That's because failures are propagated upwards through several layers using error codes, and only at the last layer is that turned into an exception. So you get a stack trace from that point upwards, which is not as helpful. Sure, but there still has to be some mechanism to pass that additional information along with the error code. (Such as Boost.LEAF.)