Git Product home page Git Product logo

raii_with's Introduction

raii

A simple library to provide RAII (or something very much like it) in standard-compliant C99, using raii_with(resource, initializer, destructor) { ... }-syntax:

#include "raii/raii.h"

int main() {

  raii_with(int *myint, safe_malloc(sizeof(int)), free){

    *myint = 10;
    printf("myint is located at %p and contains: %d\n", myint, *myint);
    printf("%s\n", __func__);
  }

  int res = safe_return_example();
  printf("res: %d\n", res);

printf("Test\n");
}

Huh?

Resource Acquisition Is Initialization (or, if you prefer, Resource Relinquishment is Destruction) is a pattern that C++ and some other languages use to ensure that a resource is automatically released once you are done working with it.

The raii library for C99 tries to emulate this, by letting you write raii_with statements that are similar to the with-statements of e.g. Python.

The advantages over managing resources manually are:

  • Manual management is error-prone:
    • Checking for proper initialization or early-fail on error requires a linear amount of cleanup lines per nested resource if writing this using if-statements.
    • The alternative, using gotos to labels at the end of the function, is prone to mistakes when new content is added to the function or the internal order of resources is swapped.
  • Using an explicit lifetime-stack object means that you need to conceptually work with this lifetime-stack all the time.

Instead, raii:

  • is built such that swapping the order of the resources will swap the order of the clean-up logic for you.
  • Variables introduced using raii_with only exist in the block you provide. Referencing after the block will result in a compiler error, so that's a whole lot of bugs you don't need to worry about anymore!
  • creates a hidden lifetime 'stack' (which is implemented as a linked-list), which you don't have to care about, because all you have to care about is that you can just use safe_return to return early from within a raii_with-block.
  • Use continue or break to jump to the end of the current raii_with-block.

How does it work?

raii uses a custom control structure macro to ensure you can pass any code block to the raii_with-statement.

For more information, you are encouraged to read the inline documentation in the raii/raii.h file.

For more information about writing Custom Control Structure Macro's, see my related library exceptional that introduces block-style exceptions to C99, and the there-linked further resources as well.

Gotcha's

  1. Do not use return from within raii_with, but only safe_return, because otherwise the destructors will not be run.
  2. Do not perform pointer-swaps with var_decl; the destructor will still be run on the original structure, because raii keeps its own reference to the resource.

I believe both of these things are very logical and easy to keep in mind. (resulting in raii being a near-leak-free abstraction). If you know of a way to further reduce these without introducing new ones, please share it!

Acknowledgements

I'd like to thank:

raii_with's People

Contributors

qqwy avatar rexim avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

raii_with's Issues

Using of return operator.

Hello...

I have a proposition.

You can redefine return operator to an expression like:

#define return (0 ? &some_var : (some_type*)0),

Then you globally define some_var with some_type and locallly (in each function, via macros providing RAII) you re-declaring some_var with some_type2. Where some_type and some_type2 must be defined just like typedef struct { int dummy[1]; } some_type.

As a result, you will get compile error if you will try to perform return from block of code where RAII is assumed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.