Example C++ function

Let us start with a simple C++ function which we wish to make available to C code:


// Fill the supplied buffer with the integer v converted to a string, returning
// length of string minus null terminator
extern "C" outcome::result<size_t> to_string(char *buffer, size_t bufferlen, int v) noexcept
{
  try
  {
    // Could throw an exception!
    std::string temp(std::to_string(v));

    // Will this string exceed the supplied buffer?
    if(temp.size() + 1 > bufferlen)
      return std::errc::no_buffer_space;

    // Copy the string into the supplied buffer, and return length of string
    memcpy(buffer, temp.data(), temp.size() + 1);
    return temp.size();
  }
  catch(...)
  {
    // This utility function rethrows the C++ exception, matching it
    // against every standard library exception and generating an
    // error code exactly matching it if possible. So, if the
    // string creation threw std::bad_alloc, that would be converted
    // into make_error_code(std::errc::not_enough_memory).
    return outcome::error_from_exception();
  }
}
View this code on Github

A surprise to some may be that one can return an outcome::result<size_t> from a C function! This is because if for some result<T, EC> where both T and EC have standard layout and are trivially copyable, then Outcome guarantees so will result<T, EC>. Thus outcome::result<size_t> is a perfectly legal C type, and can be returned directly to C code.