Re: [TECH TOPIC] Rust for Linux

Bart Van Assche
2021-07-06T21:45:53Z

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

Bart.