Hacker News new | ask | show | jobs
by epermyakov 1862 days ago
I guess the "shtick" of C is that it has a small and obvious feature set. The readability and style of programming follows from that. As you start adding more and more language features and constructs, you start getting all the other languages that were derived from C and you no longer have C.

During the development of the project, I had a thought that it would be nice to have a RAII/defer mechanism to get rid of repetitive code for freeing resources at the end of a function. But I'm not sure if that's really necessary since you can just put the 'free' calls at the end of the function and insert some labels between them in a kind of 'stack'. This perhaps is more in the spirit of the language - a bit more wordy, but having less voodoo done by the compiler.

2 comments

Some people like to make a defer macro like this:

     #define itervar(i) i##__LINE__
     #define FOR_DEFER(pre, post) for (int itervar(i) = ((pre), 0);
                               !itervar(i)++; (post))

     Foo *foos;
     FOR_DEFER(foos = alloc(Foo, 1024), free(foos))
     {
         // This "loop" only runs once.
     }
Those can be easily stacked

     FOR_DEFER(foos = alloc(Foo, 1024), free(foos))
     FOR_DEFER(bars = alloc(Bar, 1024), free(bars))
     {
          ///
     }
Here is a memory arena macro.

     #define FOR_MEMORY_ARENA(name) for DEFER(Arena name = make_arena(), free_arena(&arena))

     FOR_MEMORY_ARENA(arena)
     {
         Foo *foos = arena_alloc(&arena, Foo, 1024);
         Bar *bars = arena_alloc(&arena, Bar, 1024);
         // all allocations automatically freed at the end
     }
gcc and llvm have a cleanup attribute you can use for this. Systemd uses it.

https://fdiv.net/2015/10/08/emulating-defer-c-clang-or-gccbl...

I guess you have to be careful not to return inside of these :)
Interesting, I think defer as a statement might not be too much magic but it would be too complicated for my mostly single-pass approach.

Thank you for your response.