Skip to content

ned14/wg14_result

Repository files navigation

Reference implementation for proposed standard C result

(C) 2024 - 2026 Niall Douglas http://www.nedproductions.biz/

CI: CI

Reference API docs: https://ned14.github.io/wg14_result/

Can be configured to be a standard library implementation for your standard C library runtime. Licensed permissively.

This is a 100% C reimplementation of https://ned14.github.io/outcome/experimental/, created as Outcome.Experimental is now on the WG14 C standardisation track and I no longer participate on WG21 (C++ standards). Features:

  • 100% ABI compatible with the C++ implementation, you can freely switch between each, even by casting pointers on objects or having C++ call via virtual function into a C implementation, or vice versa.
  • Unlike the C API which C++ Outcome has shipped for years, this one does not require any C++ runtime to be linked into any final binaries.
  • Can be configured as a header-only library (unity build) which has headers also include their source files. If so:
    • The usual C 90 minimum requirement for the headers is raised to C 11, as the library source code needs minimum C 11.
    • If a C++ compiler is being used, the minimum requirement for the headers is raised to C++ 20 as previous C++ standards don't implement enough of C 11.
  • Comes with optional C++ extensions where the standard member functions for the types (i.e. default, copy, move, destruct) call the C free functions which implement those operations. This means that if you are using this library from C++, or using this library via language bindings generated from the C++, lifetime management is taken care of for you.
  • Language bindings are provided for:
    • Rust (bindings/rust) via Rust FFI bindgen.
    • SWIG
      • Python (bindings/SWIG/python)
      • Other languages SWIG supports should be trivial to add: C#, D, Go, Guile, Java, Javascript, Lua, OCaml, Octave, Perl, PHP, R, Ruby, Scilab, Tcl/Tk. And FORTRAN via a special fork of SWIG.

Example of use

// To declare to C a Result with an int value type, we use the
// WG14_RESULT_DECLARE(T, name) macro. This declares the type
// and any support functions for that type.
WG14_RESULT_DECLARE(int, int)

// We then typedef it to something concrete
typedef WG14_RESULT(int) result_int;

// A Result with a void (i.e. none) value type is predeclared. 
typedef wg14_result_with_void result_void;

// Some function returning a Result with int value type.
result_int test2(int x);

result_void test3(int x)
{
  // This is an example of a four macro argument TRY operation:
  // out, rettype, cleanup, expression.
  WG14_RESULT_TRY(
    int r /* variable to extract any successful value into */,
    void /* override the return result type */,
    printf(
      "test3 finds test1 returns failure.\n") /* cleanup to perform if TRY fails */,
    test1(x) /* result returning expression to TRY */);

  printf("test3 finds test1 returns successful value %d.\n", r);

  // This is how to return a successful Result with no value type.
  return WG14_RESULT_MAKE_SUCCESS(void, );
}

Supported targets

This library should work well on any POSIX implementation, as well as Microsoft Windows. You will need a minimum of C 11 in your toolchain to compile the library, however its header files work in all standards of C right back to C 90 (NOTE that some macros do use features from later C standards, if on an earlier C then don't use that macro).

Current CI test targets:

  • Ubuntu Linux, x64.
  • Mac OS, AArch64.
  • Microsoft Windows, x64.
  • ESP32, RISC V.

Current compilers:

  • GCC
  • clang
  • MSVC

Configuration

You can find a number of user definable macros to override in config.h. They have sensible defaults on the major platforms and toolchains.

Features from C++ status-code out of scope for the C implementation

  • status_code_errored, without Contracts it doesn't really make sense.
  • status_code mixins, which require template trait based inheritance to be easy to use.
  • quick_status_code_from_enum would need C compiler magic to work I think. Not ruling that out at all, but it's definitely a later proposal paper.
  • system_code_from_exception makes no sense without C++ exceptions.
  • C++ i/o stream support obviously makes no sense in C.

Performance

On my Threadripper 5975WX which is a 3.6Ghz processor bursting to 4.5Ghz on Linux:

todo

On a MacBook Pro M3 running ARM64

todo

On a MacBook Pro M3 running ARM64 Windows within a VM

todo

Todo

  • Ought to write how to use documentation
  • Ought to generate examples to ensure optimised codegen
  • Convenience functions for serialising and printing.
  • Rust bindings missing wrapping a Rust Result into a C Result i.e. going the other direction.
  • Need example bindings for:
    • FORTRAN
    • Swift

Features reimplemented in C from C++ status-code

  • status_code_domain
  • status_code<void> as status_code_untyped
  • status_code_generic
  • status_code(T)
  • status_code_posix
  • status_code_system
  • result(T)
  • TRY macros

After next WG14 meeting review

  • status_code_nested
  • status_code_getaddrinfo
  • status_code_http
  • status_code_win32
  • status_code_nt
  • status_code_com

Maybe in the future

  • status_code_cxx_error_code
  • status_code_boost_error_code

About

Reference implementation of proposed result for C

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

 

Packages

No packages published