I really don't want to create temporary files anymore, since that implies
removing them at some point. So I really need memfds. So I can't do your first
point.
What will you do if this feature is not available (your program is running on older kernel)?
 
Sorry, you don't get to change the API. Using the API as-is was the big
problem of your post. If you can change my API to make it better and report a
more structured set of information, then the same can be done too for
exceptions.
That is really interesting and that is what I cannot fully understand, can you please elaborate how exactly it can be done via exceptions? Of course, in a maintainable way (a way that can easily accommodate adding/removing sub-errors as well as adding new direct/indirect callers of the function in the future), without relying on documentation nor on comments etc...?
 

Your solution requires that at some point in the call stack, the error
condition be consumed and then either augmented or handled. Nothing in that
requires using return values, global/thread-local values (like errno) or
exceptions. All three are possible.
All three are possible, not all of them are as visible and explicit as return-values.
 
What you're arguing for is sanely designed API and handling error conditions
as close to the error locus as possible. I don't dispute that: that's the
proper and only way to handle errors. What I will agree with you is that using
exceptions makes it to easy *not* to do it, since you can simply "forget" to
handle, then let the error pass on to your caller. When using return values,
the error condition will often be "in your face" and you'll have a hard time
ignoring it.

But C++ does not dictate what you must do. You don't like exceptions? Or don't
feel comfortable writing code with it, like me? Then don't use them. But don't
ask that they be removed from the language. That's not going to happen.

Yes, I, probably, agree with you.
But, should not then exceptions be discouraged from using exactly as
  • bare new/malloc (in favour of make_unique/make_shared)
  • or void * (in favour of type-rich programming)
  • or default implicit constructors
are discouraged now?

Even if the answer is no, should not we add expected<> (for symmetry or as mechanism that complEments exceptions) into the standard?