Question

I want to write a library with "no resource leak guarantee" feature. So I shall know whether each method allocates any resource or not. It may change the code. For example:

void foo()
{
  methodDontAllocateAnyResources();
  methodCanThrow();
}

void bar()
  methodAllocateSomeResources();
  try{
    methodCanThrow();
  }
  catch(const std::exception& exp){
    releaseAllocatedResources();
    throw;
  }
}

Both foo() and bar() functions can throw an exception. It doesn't matter because I let exceptions to propagate. But In bar(), I must catch a possible exception to avoid a resource leak.

In the example I could decide to use or not a try-catch block easily. However, you know, normally we cannot understand whether a method allocates any resource or not by its name. So, I've decided to put this information into method documentation. Doxygen doesn't have such a tag. Also, I cannot find any web resources suggest that. Do you think using a custom @resource-allocation tag is a good idea?

Thanks

Was it helpful?

Solution

I want to write a library with "no resource leak guarantee" feature. [...] It doesn't matter because I let exceptions to propagate. But In bar(), I must catch a possible exception to avoid a resource leak.

This sounds good, all the way to the last sentence.

Consider using RAII resources and smarter return types to manage resources, instead of internal try/catch blocks.

Alternative implementation for bar:

struct raii_resource {
{
  raii_resource(type value) : value_{value} {}
  ~raii_resource() { releaseAllocatedResources(value_); }
  type value_;
}; 

void bar() {
  raii_resource r = methodAllocateSomeResources(); // returns type instance
  methodCanThrow();
}

If your function needs to return the allocated resource to the client code, simply wrap the return value in a smart wrapper (that will delete it at the end of scope).

Usually, in C++ you should only use try/catch blocks to handle errors, not to release allocated resources.

If you do this (use raii), the documentation of allocated resources will become irrelevant, because resource leaks are no longer possible.

That said, to add allocations information to the API documentation, I would add it as a @remarks or something similar.

OTHER TIPS

your goal : "no resource leak guarantee"

your propsed solution: using a custom @resource-allocation tag to document all possible resource allocations

I donot think that the idea to document resource allocation will help you to avoid resource leaks.

the chances that you forget to add the resource-documention-tag is at least as high as the chance that you forget to release a resource in a catch or finally block.

In my opition it would be better to have a declarative way to avoid resource leaks like c++ smart pointers.

java and c# have a declarative language construct "using" that takes care of resource-deallocation:

 using (MyResource r = new MyResource()) {
    doSomeThingWith(r);
 }

The compiler translates this into something like (java syntax. c++ syntax should be similar)

 MyResource r = null;
 try {
    r = new MyResource();
    doSomeThingWith(r);
 } finally {
    if (r != null) delete r;
 }

I donot know if there is something similar to "using" in the c++ world.

Simply adding tags where you allocate resources just documents where the leaks are likely to occur. It doesn't actually prevent the leak.

Use RAII when allocating leakable resources - acquire them only in constructors, and then free them in the corresponding destructors. Watch out for constructors that can throw exceptions. Either add exception handlers within the constructor to tidy up any already acquired resources, or else wrap each resource in a simple class that does its own RAII.

Beware of raw pointers - when a pointer goes out of scope, it doesn't release the thing it's pointing to. Prefer storing your RAII-wrapped reources by value, or using smart pointers which will free up the thing they point to.

Licensed under: CC-BY-SA with attribution
scroll top