RAII, how is the macro expanded?

G

G G

from Oreilly's "Understanding and Using C Pointers" pp.55-56

#define RAII_VARIABLE(vartype,varname,initval,dtor) \
void _dtor_ ## varname (vartype * v) { dtor(*v); } \
vartype varname __attribute__((cleanup(_dtor_ ## varname))) = (initval)


void raiiExample() {
RAII_VARIABLE(char*, name, (char*)malloc(32), free); strcpy(name,"RAII Example");
printf("%s\n",name);
}

how is the macro expanded using void raiiExample()

my attempt below has to be wrong.

void free name(char* *v) { free (*v);}

char* name __attribute__((cleanup(free name))) = ((char*)malloc(32))

##varname ?
__attribute__(...) ?
 
S

Stefan Ram

G G said:
how is the macro expanded

void _dtor_name (char* * v) { free(*v); } char* name __attribute__((cleanup(_dtor_name))) = ((char*)malloc(32)); strcpy(name,"RAII Example");
 
S

Stefan Ram

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 ))
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top