tags:

views:

483

answers:

6

Is it possible to implement RAII in pure C?

I assume it isn't possible in any sane way, but perhaps is it possible using some kind of dirty trick. Overloading the standard free function comes to mind or perhaps overwriting the return address on the stack so that when the function returns, it calls some other function that somehow releases resources? Or maybe with some setjmp/longjmp trick?

This is of a purely academic interest and I have no intention of actually writing such unportable and crazy code but I'm wondering if that is at all possible.

A: 

Hey, you're trying to re-create CFront!

Arkadiy
Not exactly. Cfront was a compiler that took in C++ code and produced C code. I'm looking for ways to implement a specific idiom directly in C without a preliminary phase.
gooli
@gooli: But Cfront had to generate C code that was able to handle RAII because the C++ code it was working from required that. However, that said, there was a point at which Cfront ceased to be usable, and I believe that was when exceptions appeared on the scene. That may not matter to you.
Jonathan Leffler
@Jonathan: The generated code could just call the "constructors" and "destructors" at the beginning and the end of the relevant block. Since the code is automatically generated, there is no need for magic.
gooli
+1  A: 

I'd opt for overwriting the return address on the stack. It'd work out as the most transparent. Replacing free will only work with heap-allocated "objects".

Roger Lipscombe
+2  A: 

Probably the easiest way is to use goto to jump to a label at the end of a function but that's probably too manual for the sort of thing you're looking at.

Jasper Bekkers
+13  A: 

This is inherent implementation dependent, since the Standard doesn't include such a possibility. For GCC, the cleanup attribute runs a function when a variable goes out of scope:

#include <stdio.h>

void scoped(int * pvariable) {
    printf("variable (%d) goes out of scope\n", *pvariable);
}

int main(void) {
    printf("before scope\n");
    {
        int watched __attribute__((cleanup (scoped)));
        watched = 42;
    }
    printf("after scope\n");
}

Prints:

before scope
variable (42) goes out of scope
after scope

See here

Johannes Schaub - litb
This is way neater than I thought would be possible!
gooli
+1  A: 

Have you looked at alloca()? It will free when an var leaves scope. But to use it effecticly the caller must always do the alloca before sending it to things... If you were implementing strdup, well, you can't use alloca.

nelix
A: 

If your compiler supports C99 (or even a substantial part of it) you can use a variable length array (VLA), such as:

int f(int x) { 
    int vla[x];

    // ...
}

If memory serves, gcc had/supported this feature well before it was added to C99. This is (roughly) equivalent to the simple case of:

int f(int x) { 
    int *vla=malloc(sizeof(int) *x);
    /* ... */
    free vla;
}

It does not, however, let you do any of the other things a dtor can do such as closing files, database connections, etc.

Jerry Coffin