Reputation: 3740
Is it possible to prevent or detect the following bug, in any way (static analysis), where the stack allocated object is not captured and goes out of scope on the same line that it was constructed?
Resource resourceA, resourceB;
void someFunction()
{
ScopedResourceBinder resourceBindA( resourceA );
ScopedResourceBinder( resourceB ); // <--- BUG
}
The first ScopedResourceBinder
is correct, but the second one doesn't do anything, since it immediately 'unbinds' right after it 'binds' (hypothetically speaking).
This is clearly a programmers error, but I have debugged this a few times now (for hours on a couple occassion) and it is extremely difficult to spot. Once you see it you think "ah that was a stupid one", but in practice, it is easy to make the mistake and the compiler is defenseless... or is it?
Background info: I work with a library that makes heavy use RAII class for pushing an popping state, for example OpenGL resources. Managing the bindings with scope is a big improvement of manually calling bind() / unbind() functions, but the potential bug listed here comes up with this new pattern.
Upvotes: 5
Views: 146
Reputation: 366
In general coding practice, we should explicitly express our intent in the class definition itself.
For eg:
If we want to have singleton class, then all the constructors should be made private.
If we want to constructs an object with some variables, then only the required constructor should be exposed publicly, rest all should be mentioned as private.
In this manner we would be able to flag all wrong usage during compile time only.
Upvotes: 0
Reputation: 141554
ScopedResourceBinder( resourceB );
is the same as ScopedResourceBinder resourceB;
, i.e. it declares a named variable with name resourceB
, calling the default constructor of ScopedResourceBinder
.
This persists until the end of the function, however it is still a bug because it does not carry out your intent of binding to the variable resourceB
.
To prevent this particular case you could make sure that ScopedResourceBinder
does not have a default constructor.
Upvotes: 2