C Results

The C macro API header <outcome/experimental/result.h> has some macros for working with any kind of Result:

CXX_DECLARE_RESULT(ident, T, E)
Declares to C a basic_result type uniquely identified by ident. T is available at the member variable .value, and E is available at the member variable .error. If you call this from within C++, make SURE it is not within a extern "C" block!
CXX_RESULT(ident)
A reference to a previously declared result type with unique ident.
CXX_RESULT_HAS_VALUE(r)
Evaluates to 1 (true) if the input result has a value.
CXX_RESULT_HAS_ERROR(r)
Evaluates to 1 (true) if the input result has an error.
CXX_RESULT_ERROR_IS_ERRNO(r)
Evaluates to 1 (true) if the input result's error value is a code in the POSIX errno domain.

The above let you work, somewhat awkwardly, with any C-compatible basic_result<T, E>. basic_result<T, E> is trivially copyable and standard layout if its T and E are both so, and it has the C layout:

struct cxx_result_##ident
{
  union
  {
    T value;
    E error;
  };
  unsigned flags;
};

Note that this layout is different to that of CXX_DECLARE_STATUS_CODE as the C++ result has a different layout if E is a status code.