https://gustedt.wordpress.com/2022/01/15/a-defer-feature-using-lambda-expressions/ Skip to content Jens Gustedt's Blog A defer feature using lambda expressions In the previous post https://gustedt.wordpress.com/2020/12/14/ a-defer-mechanism-for-c/ I already presented an idea for a defer feature for C, namely a feature that would provide a simple mechanism to cleanup at the end of a block, regardless how that block is left. There are many different extension out there that provide such a feature, for example POSIX' pthread_cleanup_push and pthread_cleanup_pop, Microsoft's __try and __finally and gcc's cleanup attribute. Although they are used quite often, none of these extension has yet been adopted widely enough to prefer it over the others for standardization. In a new paper A simple defer feature for C we present a much simpler version of a unifying framework for such cleanup features which is conditionned to the acceptance of lambdas into C23: defer lambda-expression; Using lambda expressions for this feature helps to clarify which evaluation stratgy is applied for the code inside the depending block. In fact, it has been much debated if variables used in the depending block should be evaluated at the point of the defer itself, or at the end when it is executed. This debate has been as fruiteless as for lambdas, compound expressions or nested functions: there is not one "natural" approach for that in C. For lambdas WG21 (C++) has been well advised to leave this entirely to the user of the feature, namely to the specification of the capture clause of the lambda. So using a lambda expression for defer just uses that same strategy, the variables from the surrounding scope that are used by a defer will simply depend on the capture clause of the lambda expression. (For the terminlogy for lambdas and their captures that I apply see the latest lambda proposal for C23.) In the following example, the values of p, code>q and r are used as arguments to free at the end of the execution of main. Because the corresponding capture is a shadow capture, for p the initial value is used as argument to the call; for q it is an identifier capture and thus the value is used that was stored last before a return statement is met or the execution of the function body ends. Similarly, for r the value capture rp has the address of r and frees the last allocation for which the address was stored in r. The four return statements are all valid and according to the control flow that is taken the function executes 0, 1, 2, or 3 defer callbacks. If at least the first three allocations are successful, the storage is freed in the order r, q and p. If the call to realloc fails, the initial value of q is passed as argument to free. #include int main(void) { double*const p = malloc(sizeof(double[23])); if (!p) return EXIT_FAILURE; defer [p]{ free(p); }; double* q = malloc(sizeof(double[23])); if (!q) return EXIT_FAILURE; defer [&q]{ free(q); }; double* r = malloc(sizeof(double[23])); if (!r) return EXIT_FAILURE; defer [rp = &r]{ free(*rp); }; { double* s = realloc(q, sizeof(double[32])); if (s) q = s; else return EXIT_FAILURE; } } Because lambda expressions are "just" values, it is much more natural to model this version of the defer feature as a defer declaration. If you have a background in C++ you can simply think of it as a declaration of an unamend object of lambda type for which the destructor does nothing else than to call the lambda with no parameters. In fact, it is a nice exercise to implement such a feature in C++ by declaring a hidden variable of a specific class type that has a constructor (from a lambda or so) and a destructor as only members, and then wrap such a thing in a macro (yes!) named defer. Other properties of defer declarations are left open and are specified to be implementation defined: * Is defer allowed in any block or just for the function body itself? * What happens for preliminary exits of the thread or of the whole execution? * What happens with signals? For example, for the first an imlementation that would solely build on gcc's cleanup attribute could choose to restrict defer to the toplevel block of the function. Also this proposal puts asside other related features that were discussed in the orginal paper such as panic and recover. Such extensions, that not yet have so much implementation experience in C, may be left to a new technical specification (TS) that WG14 prospects for this whole feature. Share this: * Share * * Email * Print * * Facebook * Twitter * * Related [c3fbd]Author Jens GustedtPosted on January 15, 2022January 15, 2022 Categories C23 Leave a Reply Cancel reply Enter your comment here... [ ] Please log in using one of these methods to post your comment: * * * * Gravatar Email (required) (Address never made public) [ ] Name (required) [ ] Website [ ] WordPress.com Logo You are commenting using your WordPress.com account. ( Log Out / Change ) Google photo You are commenting using your Google account. ( Log Out / Change ) Twitter picture You are commenting using your Twitter account. ( Log Out / Change ) Facebook photo You are commenting using your Facebook account. ( Log Out / Change ) Cancel Connecting to %s [ ] Notify me of new comments via email. [ ] Notify me of new posts via email. [Post Comment] [ ] [ ] [ ] [ ] [ ] [ ] [ ] D[ ] This site uses Akismet to reduce spam. Learn how your comment data is processed. Post navigation Previous Previous post: type-safe parametric polymorphism [c3fbdd40] C as a language [gustedt-modernc-hi-band] Copyright (c) 2010-2019 Jens Gustedt, Strasbourg, France P99 macros for C99 emulation of C11 Categories * C++ (10) * C11 (43) + defects (11) + feature request (2) + library (9) * C17 (10) * C2x (10) + C23 (3) * C99 (69) + integers (11) + language (31) + P99 (17) + preprocessor (12) + syntax (15) * compiler optimization (4) * core (3) * lock structures (8) * Modular C (5) * POSIX (13) + linux (2) * rants (5) * Uncategorized (1) Recent Posts * A defer feature using lambda expressions * type-safe parametric polymorphism * Feature freeze for C23 * Improve type generic programming * A defer mechanism for C Top Posts & Pages * A defer feature using lambda expressions * A defer mechanism for C * Modern C, Second Edition * Detect empty macro arguments * Default arguments for C99 * type-safe parametric polymorphism * Simple C11 atomics: atomic_flag * testing compile time constness and null pointers with C11's _Generic * VLA as function arguments * Myth and reality about inline in C99 Search for: [ ] Search related * C99 * c threads * preprocessor Follow Blog via Email Enter your email address to follow this blog and receive notifications of new posts by email. Join 175 other followers Email Address: [ ] Follow Meta * Register * Log in * Entries feed * Comments feed * WordPress.com Archives * January 2022 * October 2021 * January 2021 * December 2020 * November 2020 * June 2020 * May 2020 * March 2020 * September 2019 * August 2018 * June 2018 * April 2018 * August 2017 * May 2017 * March 2017 * January 2017 * November 2016 * September 2016 * August 2016 * July 2016 * July 2015 * May 2015 * April 2015 * February 2015 * October 2014 * September 2014 * April 2014 * December 2013 * October 2013 * August 2013 * July 2013 * February 2013 * December 2012 * November 2012 * October 2012 * August 2012 * July 2012 * May 2012 * April 2012 * March 2012 * February 2012 * January 2012 * December 2011 * November 2011 * October 2011 * July 2011 * June 2011 * March 2011 * February 2011 * January 2011 * December 2010 * November 2010 * October 2010 * September 2010 * August 2010 * July 2010 * June 2010 RSS RSS Feed RSS - Posts RSS Feed RSS - Comments Jens Gustedt's Blog Create a free website or blog at WordPress.com. [Close and accept] Privacy & Cookies: This site uses cookies. By continuing to use this website, you agree to their use. To find out more, including how to control cookies, see here: Cookie Policy * Follow Following + [wpcom-] Jens Gustedt's Blog Join 175 other followers [ ] Sign me up + Already have a WordPress.com account? Log in now. * + [wpcom-] Jens Gustedt's Blog + Customize + Follow Following + Sign up + Log in + Copy shortlink + Report this content + View post in Reader + Manage subscriptions + Collapse this bar Send to Email Address [ ] Your Name [ ] Your Email Address [ ] [ ] loading [Send Email] Cancel Post was not sent - check your email addresses! Email check failed, please try again Sorry, your blog cannot share posts by email. [b]