Re: [TECH TOPIC] Rust for Linux

Stephen Hemminger
2021-07-06T23:09:01Z

On Tue, 6 Jul 2021 14:45:50 -0700
Bart Van Assche <bvanassche@acm.org> wrote:

> On 7/6/21 1:00 PM, Roland Dreier wrote:
> > One area I see where Rust could make a big improvement for drivers is
> > in using RAII for error paths. Drivers often have a lot of code like
> >
> > if (something())
> > return err;
> >
> > if (something_else())
> > goto undo_something;
> >
> > if (a_third_thing())
> > goto undo_two_things;
> >
> > and so on, which is difficult to get right in the first place and even
> > harder to keep correct in the face of changes.
>
> Although cumbersome, it is possible to implement RAII by using the gcc
> extensions to the C language. An example:
>
> #include <stdio.h>
> #include <stdlib.h>
>
> #define CONCAT2(a, b) a##b
> #define CONCAT(a, b) CONCAT2(a, b)
> #define DECL_WITH_DTOR_NAME(declaration, initializer, cleanup_func_name,\
> arglist, cleanup_func_body) \
> void cleanup_func_name(arglist) { cleanup_func_body; } \
> declaration __attribute__((cleanup(cleanup_func_name))) = initializer
> #define DECL_WITH_DTOR(declaration, initializer, arglist, cleanup_func_body) \
> DECL_WITH_DTOR_NAME(declaration, initializer, \
> CONCAT(cleanup_func, __COUNTER__), arglist, \
> cleanup_func_body)
>
> int main(int argc, char** argv)
> {
> DECL_WITH_DTOR(void *p, NULL, void **p,
> printf("freeing p = %p\n", *p); free(*p););
> DECL_WITH_DTOR(void *q, NULL, void **q,
> printf("freeing q = %p\n", *q); free(*q););
> p = malloc(7);
> q = malloc(3);
> printf("p = %p; q = %p\n", p, q);
> return 0;
> }
>
> The output of the above code:
>
> p = 0xd952a0; q = 0xd952c0
> freeing q = 0xd952c0
> freeing p = 0xd952a0
>

Why not use the GCC cleanup function attribute, it is a lot cleaner than
having ugly error prone macros.

#define _cleanup_free __atttribute__((__cleanup__(free)))

int main(int argc, char **argv)
{
_cleanup_free_ void *p;
_cleanup_free_ void *q;