Claudio Fontana <cfont...@suse.de> writes: > On 9/22/22 15:20, Markus Armbruster wrote: >> Claudio Fontana <cfont...@suse.de> writes: >> >> [...] >> >>> I think it would be better to completely make the return value separate >>> from the Error, >>> and really treat Error as an exception and not mix it up with the regular >>> execution, >>> >>> but if it is the general consensus that I am the only one seeing this >>> conflation problem we can model it this way too. >> >> It's a matter of language pragmatics. In Java, you throw an exception >> on error. In C, you return an error value. >> >> Trying to emulate exceptions in C might be even more unadvisable than >> trying to avoid them in Java. Best to work with the language, not >> against it. >> >> Trouble is the error values we can conveniently return in C can't convey >> enough information. So we use Error for that. Just like GLib uses > > Right, we use Error for that and that's fine, but we should use it _only > Error_ for that. > > Ie map the Exceptions directly to Error. > > So: > > try { > > rv = function_call(...); > > use_return_value(rv); > > } catch (Exception e) { > > /* handle exceptional case */ > > } > > becomes > > rv = function_call(..., Error **errp); > > if (errp) { > /* handle exceptional case */ > } > > use_return_value(rv);
This is simply not the intended use of Error. Also, "trying to emulate exceptions in C might be even more unadvisable than trying to avoid them in Java." > Instead we mix up the Exception code path and the regular code path, by > having rv carry a mix of the Exception and regular return value, > and this creates problems and confusion. "In C, you return an error value." > If we put a hard line between the two, I think more clarity emerges. Maybe, but consistency matters. Clarity doesn't emerge in isolation. Deviating from prevailing usage tends to confuse. >> GError. >> >> More modern languages do "return error value" much better than C can. C >> is what it is. >> >> We could certainly argue how to do better than we do now in QEMU's C >> code. However, the Error API is used all over the place, which makes >> changing it expensive. "Rethinking the whole Error API" (your words) >> would have to generate benefits worth this expense. Which seems >> unlikely. >> >> [...] >> > > This is all fine, the problem is how we remodel this in C. > > This is how I see the next steps to clarify my position: > > short term: > > - keep the existing API with the existing assumptions, use a separate > argument to carry the pointer to the actual return value (where the function > return value as provided by the language is used to return if an exception > was generated or not, as we assume today). We don't actually need separate values for "actual return value" and "success vs. failure" here. We can easily encode them in a single return value. This is *common* in C, for better or worse. For instance, read() returns -1 on error, 0 on EOF (which is not an error), and a positive value on actual read. On error, @errno is set, which is a bit awkward (we wouldn't design that way today, I hope). The interface I proposed is similar: return -1 on error, 0 on not found (which is not an error), and 1 on successful load. On error, an Error is set via @errp. With a name that makes it obvious that "not found" is not an error, there's nothing that should surprise someone passingly familiar with QEMU code. > - long term (maybe): fix the existing API by detaching completely the return > value from the exception. As I wrote, this seems unlikely to be worth its considerable expense. > Wdyt? > > C