Boost logo

Boost :

From: Andrzej Krzemienski (akrzemi1_at_[hidden])
Date: 2025-04-30 07:12:15


śr., 30 kwi 2025 o 03:16 Jean-Louis Leroy via Boost <boost_at_[hidden]>
napisał(a):

> Hi Andrzej,
>
> Thank you for your input.
>
> > > When an error is encountered, the program is terminated by a call to
> abort.
> >
> > And then in the next sentence it talks about different debug and release
> > policies, and ultimately, I do not know if by default abort() is called
> or
> > not.
>
> The entire paragraph reads:
>
> > When an error is encountered, the program is terminated by a call to
> abort. If
> > the policy contains an error_handler facet, it provides an error member
> > function (or overloaded functions) to be called with an object
> identifying the
> > error. The release and debug policies implement the error facet with
> > vectored_error_handler, which wraps the error object in a variant, and
> calls a
> > handler via a std::function. By default, it prints a description of the
> error
> > to stderr in the debug policy, and does nothing in the release policy.
>
> It is intended to say "abort is called", but in debug builds (only) you
> get an
> error message.
>
> But I can see how all the verbiage can be confusing. It is important to me
> that
> error processing be customizable. That's what policies are for. But that
> is also
> an "advanced feature". I did not want to write something that is incorrect
> (diagnostic in debug builds only, abort always) because error handling is
> customizable. The flip side is that I wrote something obscure.
>
> I am beginning to think that I should split the tutorials in two parts:
>
> Tutorials
> hello world
> multiple dispatch
> headers and namespaces
> friendship
> smart pointers
> error handling
> high-level explanation of what an "error" is
> HERE just say "abort always", with diagnostics in debug builds
> (don't mention policies)
> performance
> Advanced features
> virtual ptr alternatives
> core api
> policies
> custom advanced error handling
> custom rtti
> dynamic loading
>
>
> > So, I dun a Compiler Explorer test:
> > https://godbolt.org/z/3fW8j4eTM
> > And indeed, I get something that looks like abort()
>
> What you get is a SIGSEGV, and that is because you did not register class
> YNode
> - which is the dynamic type of `n`. In release mode there are no checks,
> whatsoever. The perfect hash function works only with inputs from its
> domain. Otherwise it returns a random value. Let's fix this:
> https://godbolt.org/z/31abxnTPv
>
> At this point I was very surprised to still get a SIGSEGV. When I compile
> locally, I get a SIGABRT as expected - we are calling the method with a
> virtual tuple that doesn't have a matching overrider.
>
> Then I tried:
>
> > #include <stdlib.h>
> >
> > int main() {
> > abort();
> > return 0;
> > }
>
> With your choice of compiler, CE says: Program terminated with signal:
> SIGSEGV.
> See https://godbolt.org/z/c69d76feE
>
> > This is the worst thing that can happen: a random runtime behavior. Is
> this
> > a bug? Or am I missing something?
>
> I agree with you, `abort` has a random runtime behavior, SIGABRT or
> SIGSEGV,
> god(bolt) knows why, that is baaad ;-) ;-)
>
> > But when I wrap the call into a try-catch block, all of a sudden, the
> > implementation seems to pick the wrong overrider and return a value,
> > clearly not the intended one. And the program goes on:
> > https://godbolt.org/z/Y6z3o56h5
>
> Let's add an executor, shall we? https://godbolt.org/z/8sf3GsTrc Now we
> get:
>
> > Program returned: 139.
> > Program stderr
> > Program terminated with signal: SIGSEGV
>
> For the same reason: YClass is not registered. Let's register it:
> https://godbolt.org/z/WqTMxhn94 ... and now we get a SIGSEGV again, which
> seems
> to be what `abort` does in these examples.
>
> Let's switch to a debug build: https://godbolt.org/z/EK5nz3daz
>
> Now we get:
>
> > Program returned: 139
> > Program stderr
> > no applicable overrider for
> boost::openmethod::method<value_boost_openmethod
> > (boost::openmethod::virtual_ptr<Node, >
> boost::openmethod::policies::debug>),
> > int, boost::openmethod::policies::debug>(void)
> > Program terminated with signal: SIGSEGV
>
> Better!
>
> You did help me find a bug though. Let's reinstate the error (the missing
> YNode
> registration) and compile again in debug mode. This is wrong:
> https://godbolt.org/z/57xorYsGT The program is incorrect all right, but,
> in
> *debug* mode, you should get an error. Something was lost in translation
> from
> YOMM2 to OpenMethod.
>
> I created a "review" branch where I will put code and doc fixes. Here is
> what
> you get with the fix: https://godbolt.org/z/WGEn3xvG6
>
> > Program returned: 139
> > Program stderr
> > unknown class YNode
> > Program terminated with signal: SIGSEGV
>
> ...which is the intended output.
>
> I should write a troubleshooting guide.
>
> > Next question that naturally arises: how do I declare `noexcept` open
> > methods with this library?
>
> I took a shot at implementing noexcept support. It was not difficult. I
> didn't
> keep it because MSVC was not capable enough. And also because noexcept
> didn't
> seem hugely useful outside of specific contexts which, I believe, don't
> intersect much with the contexts where open-methods make sense. But I am
> super
> flexible on this, I can bring back noexcept support for capable compilers.

Thanks JL. Continuing on the `noexcept` aspect, I think (but I didn't have
a look at the implementation) that providing noexcept support is
impossible, given the presence of those advanced policies for
error-reporting. That is, if you allow a remote possibility of installing
an error-handling policy that could throw, you automatically say that the
open methods can potentially throw. And adding a conditional
guarantee (noexcept only under some policies) would be even worse.

I agree with your observation that noexcept, when used correctly, is used
*very sparingly*: only in move constructors; and that it does not belong in
open methods. I should have stated this more clearly. I simply request that
the docs state explicitly that any open method is potentially throwing and
you cannot declare them noexcept.

Regards,
&rzej;


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk