mantler
mantler

Reputation: 889

Is it possible to adapt unique_ptr for use in plain c?

Is it possible to adapt unique_ptr for plain c?

Perhaps if there is a way of simulating calls to a home made "constructor/destructor" when calling malloc/free?

Is it doable? Or is it just a silly idea?

Upvotes: 3

Views: 2961

Answers (4)

Tamás Szelei
Tamás Szelei

Reputation: 23961

No, not in plain C. You can do something similar with the cleanup GCC attribute (it is not standard):

#include <stdio.h>

void scope_leaving(int* p) 
{
    printf("Leaving scope.\n");
    // this is essentially your "destructor"
}

int main(int argc, char* argv[]) 
{
    printf("Before x is declared.\n");
    {
        int x __attribute__((cleanup (scope_leaving)));
        x = 42;
    }
    printf("Scope was left.\n");
}

As you would expect, the output is this:

Before x is declared.
Leaving scope.
Scope was left.

With this, you can implement a pointer emulates the RAII semantics of unique_ptr, maybe using a macro for easier declaration. There is more to unique_ptr than that, but I'm not sure from your question if you want other aspects besides RAII.

Upvotes: 3

user1202136
user1202136

Reputation: 11567

In order to implemented unique_ptr, you need two things:

  1. assignment operator which transfers ownership;
  2. destructor for when unique_ptr goes out-of-scope.

In order to implement (1), since C does not allow you to have function overloading, you need to "discipline" yourself and always call a custom assignment function or macro. C cannot force you to always have ownership transferred.

As for (2), GCC provides an extension: you are allow to assign a "cleanup" function, which is called once a variable gets out of scope. This can be used to implement a destructor for your unique_ptr.

Upvotes: 0

MSalters
MSalters

Reputation: 179981

On second reading, there's nothing that prevents your C structures from starting with a void(*)() pointer. If you have a custom_malloc(size_t size, void(*deleter)() which sets the pointer, your custom_free(void*) can subsequently call that deleter. This is similar to a virtual destructor from C++. However, the second part of std::unique_ptr is a delete'd copy constructor. You can't do that in C.

Upvotes: 2

Mark Ransom
Mark Ransom

Reputation: 308402

The whole point of a "smart pointer" is to do certain tasks automatically on destruction. Since C doesn't have destructors there's no way to accomplish this except with explicit function calls - but that's how you deallocate memory in C already.

You could possibly make a list of pointers that need to be freed and do them all at the same time with a single function call.

Upvotes: 7

Related Questions