[HN Gopher] Braiding the spaghetti: implementing defer in the pr...
___________________________________________________________________
Braiding the spaghetti: implementing defer in the preprocessor
Author : ingve
Score : 34 points
Date : 2024-09-12 10:56 UTC (4 days ago)
(HTM) web link (gustedt.wordpress.com)
(TXT) w3m dump (gustedt.wordpress.com)
| pif wrote:
| If you want to use RAII in C, just use the "cleanup" attribute of
| gcc.
|
| https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attribute...
| wffurr wrote:
| *in non portable non standard C
| gobblegobble2 wrote:
| Supported by both gcc and clang, so portable enough for most
| people. I also like glib's cleanup attribute wrappers:
| https://docs.gtk.org/glib/auto-cleanup.html.
| wyldfire wrote:
| It is non portable, that's true. But defer [1] is at least
| undergoing discussions w/the standard committee. Didn't make
| it into C23 but maybe next time.
|
| [1] https://www.open-
| std.org/jtc1/sc22/wg14/www/docs/n2895.htm
| gustedt wrote:
| That's not very practical if you have several operations to
| perform, you'd have to create a specialized function each time.
| So no, that extension is not an alternative to designing a new
| flow control feature. (And it is not new, other languages have
| it already.)
| teo_zero wrote:
| How would the proposed solution work with this code?
| void foo() { char *p = malloc(...); defer
| free(p); ... { FILE *p = fopen(...);
| defer fclose(p); ... } return; }
|
| Would it run both deferred statements, each with the correct
| argument?
| gustedt wrote:
| Yes, the visibility rules for variables remain exactly the
| same. The dependent statement of a defer lives in the same
| scope as the defer is placed.
| aedrax wrote:
| shameless plug for my defer header:
| https://github.com/aedrax/defer.h
| andrewla wrote:
| I love the idea of having a defer statement in general for C, but
| given the complexity of C scopes it's a little hard to wrangle
| (switch statements in particular break a lot of assumptions about
| how scopes should work).
|
| I would prefer a directly scoped syntax similar for a for
| statement, something like defer (void * p =
| malloc(17); free(p)) { ... }
|
| This gets more cumbersome as you have more such scopes in a
| function, but it gives a sane bounding. You can sort of do this
| now with a properly constructed for loop so that it cleans up on
| regular exit from the loop, but it can't handle exception exits
| (returns, breaks, and god forbid goto or longjmp).
| gustedt wrote:
| This would be much more restrictive that what is proposed,
| because usually you would add `defer` statements as you go in a
| block, when you allocate more resources for example.
|
| Also usually you should be able to have several actions,
| defer { one; two; }
|
| And the bounding in the proposed feature is sane, I think, it
| is the surrounding compound statement (AKA `{ ... }` block).
| sirwhinesalot wrote:
| You can implement an acceptable defer with the standard
| preprocessor and some switch abuse.
|
| The only annoying part is needing to use "defer_return" and such
| instead of the proper keywords.
|
| Unlike most defer implementations for C this doesn't need a
| function-scope fixed sized block, it's all properly scoped, the
| switch effectively models a state machine. Similar tricks can be
| used to implement yield and such.
| sim7c00 wrote:
| the amount of effort going into people either:
|
| - straightup forgetting to free shit - writing horrible to read
| code making it impossible to do cleanup or track allocations
|
| why try to make c into c++ or rust? those languages already
| exist.
___________________________________________________________________
(page generated 2024-09-16 23:01 UTC)