void _dtor_name (char* * v) { free(*v); } char* name __attribute__((cleanup(_dtor_name))) = ((char*)malloc(32)); strcpy(name,"RAII Example");
My style is more like:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void use( char * const buff32 )
{ strncpy( buff32, "clean example", 32 );
puts( buff32 ); }
int main( void ){ char * const buff32 = malloc( 32 ); if( buff32 )
{ use( buff32 ); free( buff32 ); }}
Regarding RAII in C, I quote from one of my previous posts.
(I have just [in 2014] edited the line with »#define MALLOC«
to correct what now [in 2014] seemed to be an error,
and I have edited typos.)
The rest of this post contains only the (slightly edited)
quotation of a post of mine from 2006. (I posted this
technique in 2004, but invented many years before 2004.)
Newsgroups: comp.lang.functional
Subject: Re: Monadic combinators for scoped resource management
From: (e-mail address removed)-berlin.de (Stefan Ram)
Message-ID: <
[email protected]>
Vesa Karvonen said:
Instead of writing such deeply nested code, let's invent a couple of
combinators for combining scoped resource management functions.
Some years ago, I made up something like this for C.
Admittedly, C is not a functional programming language.
However, my idea was the same: turn nested code into a
non-nested sequence. So the source code will be a sequence,
while the execution while be "nested".
I wrote macros, so that one can write the following
to open to files and allocate memory:
FOPEN( source, "source", "r" )
FOPEN( target, "target", "w" )
MALLOC( buff, 1024 )
copy( target, source, buff );
What is happening behind the scene is, that this will also
close the files and deallocate the buffer after the copy-call
is finished. Moreover, it will only proceed to the copy call
if all resources have been obtained and it will only release
those resources which have been obtained successfully before.
So, what the above sequence really does will be like:
if( source = fopen( "source", "r" ))
{ if( target = fopen( "target", "w" ))
{ if( buffer = malloc( 1024 ))
{ result = buffcopy( target, source, buffer );
free( buffer ); }
fclose( target ); }
fclose( source ); }
Here are the definitions of the macros:
#define TRY(x) for( int try=1; (try&&(x));
#define PUSH(y) ((try=0),(y)))
#define MALLOC(var,size) TRY( var = malloc( size )) PUSH( free( var ))
#define FOPEN( var, name, mode ) TRY( var = fopen( name, mode )) PUSH( fclose( var ))