Exception guarantee question

N

Noah Roberts

If you have a member function like:

void add_job(std::auto_ptr<job> new_job)
{
jobs.push_back(new_job.get());
job.release();
}

can this be said to provide the strong guarantee? We know that both
get and release have no-throw, so the only point of failure is
push_back, which will fail if there's a memory allocation issue (since
ptr = ptr can't throw either). Under such a condition nothing is
changed about the jobs container, but the new_job is destroyed.

Because something changed, new job was destroyed, when an exception
was thrown I'm tempted to say it doesn't provide the strong
guarantee. On the other hand, the interface of the function
stipulates that ownership is being transfered and so cleaning up is
the right thing to do and perhaps fits the strong guarantee.

What do you think?
 
A

Alf P. Steinbach

If you have a member function like:

void add_job(std::auto_ptr<job> new_job)
{
jobs.push_back(new_job.get());
job.release();
}

can this be said to provide the strong guarantee? We know that both
get and release have no-throw, so the only point of failure is
push_back, which will fail if there's a memory allocation issue (since
ptr = ptr can't throw either). Under such a condition nothing is
changed about the jobs container, but the new_job is destroyed.

Because something changed, new job was destroyed, when an exception
was thrown I'm tempted to say it doesn't provide the strong
guarantee. On the other hand, the interface of the function
stipulates that ownership is being transfered and so cleaning up is
the right thing to do and perhaps fits the strong guarantee.

What do you think?

I think if you're using Dave Abraham's terminology, then it's sort of
weak guarantee: does mess up a bit (destroying that object), something's
changed after the call, but it preserves invariants.

The main issue is that the call messes with state at the call site.

In contrast, ...

void add_job( job* new_job)
{
std::auto_ptr<job> auto_destroy(new_job);
jobs.push_back(new_job.get());
auto_destroy.release();
}

does not have such an issue.

But I think better than trying to assign a generic category name,

just document the actual guarantee. :)


Cheers & hth.,

- Alf
 
W

Werner

If you have a member function like:

void add_job(std::auto_ptr<job> new_job)
{
  jobs.push_back(new_job.get());
  job.release();

}

From Herb Sutter's Item 22 in "More Exceptional C++":

"If an exception is thrown, program state remains unchanged"...
"implies commit/rollback semantics".

I would say from the callers perspective this is not the case,
as the auto_ptr will certainly be modified, but if add_job were
a member function of a class, the state of that class would
remain unchanged (and to me that is the effect that you are
looking for). Therefore the definition of strong guarantee
depends on what one considers "the program". The strong
guarantee would certainly hold for the the state inside
the function, but not for the auto_ptr.

OTOH the reason you are using an auto_ptr in the first place
is to communicate the fact that ownership "shall" be
transferred (you are forcing it). To me intent is conveyed
by using the auto_ptr in this case, and I would prefer your
solution to Alf's.

When I see and auto_ptr parameter, I know better than to touch
the auto_ptr after the call. When I see a "bald" pointer
parameter, I might as well delete the pointer after the call...

add_job( job );
delete job; //Was it cloned??? Ownership???

Regards,

Werner
 

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,581
Members
45,056
Latest member
GlycogenSupporthealth

Latest Threads

Top