Go Back   Rhinocerus > Newsgroup > Newsgroup comp.language.c++ > Newsgroup comp.language.c++.moderated

Reply
 
Thread Tools Display Modes
  #1 (permalink)  
Old 11-05-2005, 01:31 PM
Calum Grant
Guest
 
Posts: n/a
Default How to make the following exception-neutral

I was wondering how the following function could be made exception-
neutral:

std::vector<std::string> list1, list2;

void f(std::string const &x)
{
list1.push_back(x);
list2.push_back(x);
}

What if you couldn't redesign the problem and list1 and list2 needed to
be separate?

Is there any way for f() to be guaranteed exception-neutral (by the
standard), and efficient (i.e. O(1))?? The only approaches I can think
of involve a pop_back() (which is not guaranteed by the standard), or a
copy, which is not efficient.

void f2(std::string const &x)
{
list1.push_back(x);
try
{
list2.push_back(x);
}
catch(...)
{
list1.pop_back(); // Might throw?
throw;
}
}

void f3(std::string const &x)
{
std::vector<std::string> tmp1(list1); // Inefficient
std::vector<std::string> tmp2(list2); // Inefficient
tmp1.push_back(x);
tmp2.push_back(x);
list1.swap(tmp1);
list2.swap(tmp2);
}


void f4(std::string const &x)
{
std::vector<std::string> tmp(list1); // Inefficient
tmp.push_back(x);
list2.push_back(x); // Assume exception-neutral?
list1.swap(tmp);
}

Which is best?

Is it safe to even assume that std::vector:ush_back() is
exception-neutral? Any sane implementation would be, but I don't see it
documented anywhere. But it might even be plausible for
std::vector:op_back() to throw, if for example it decided to
automatically reduce its allocated size to save space, but in doing so
manages to throw in a copy constructor?

Calum

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
Alt Today
Advertising
 
and become member of Rhinocerus
Standard Sponsored Links

  #2 (permalink)  
Old 11-06-2005, 11:12 AM
Valentin Samko
Guest
 
Posts: n/a
Default Re: How to make the following exception-neutral

Calum Grant wrote:
> I was wondering how the following function could be made exception-
> neutral:
> std::vector<std::string> list1, list2;
>
> void f(std::string const &x)
> {
> list1.push_back(x);
> list2.push_back(x);
> }


> The only approaches I can think of involve a pop_back() (which is not guaranteed by the standard)


Why do you think pop_back is not guaranteed by the standard? Also, the standard requires
that pop_back does not throw.

> void f2(std::string const &x)
> {
> list1.push_back(x);
> try
> {
> list2.push_back(x);
> }
> catch(...)
> {
> list1.pop_back(); // Might throw?
> throw;
> }
> }

Yes, this is correct, except from the comment.

> Is it safe to even assume that std::vector:ush_back() is
> exception-neutral? Any sane implementation would be, but I don't see it
> documented anywhere.

Independently of push_back implementation, your copy constructor, operator = , or
allocator may throw, and exception would be propagated to your code.

> But it might even be plausible for std::vector:op_back() to throw

No, this is not allowed by the standard.

--

Valentin Samko - http://www.valentinsamko.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #3 (permalink)  
Old 11-06-2005, 11:13 AM
David Abrahams
Guest
 
Posts: n/a
Default Re: How to make the following exception-neutral

Calum Grant <calumg@onetelc.om> writes:

> I was wondering how the following function could be made exception-
> neutral:
>
> std::vector<std::string> list1, list2;
>
> void f(std::string const &x)
> {
> list1.push_back(x);
> list2.push_back(x);
> }


It's already exception-neutral.

> What if you couldn't redesign the problem and list1 and list2 needed
> to be separate?


I think you're looking for the answer to, "how can it be made to give
the strong guarantee?"

> Is there any way for f() to be guaranteed exception-neutral (by the
> standard), and efficient (i.e. O(1))?? The only approaches I can think
> of involve a pop_back() (which is not guaranteed by the standard)


Not guaranteed how?

> or a copy, which is not efficient.
>
> void f2(std::string const &x)
> {
> list1.push_back(x);
> try
> {
> list2.push_back(x);
> }
> catch(...)
> {
> list1.pop_back(); // Might throw?


No, it's guaranteed not to throw.

23.1 Container requirements 23 Containers library

10 Unless otherwise specified (see 23.2.1.3 and 23.2.4.3) all
container types defined in this clause meet the following additional
requirements:

* if an exception is thrown by an insert() function while inserting
a single element, that function has no effects.

* if an exception is thrown by a push_back() or push_front()
function, that function has no effects.

* no erase(), pop_back() or pop_front() function throws an exception.


> throw;
> }
> }
>
> Is it safe to even assume that std::vector:ush_back() is
> exception-neutral?


Almost, but not quite. However, it's safe to assume it gives the
strong guarantee. See the 2nd bullet above.

> Any sane implementation would be, but I don't see it documented
> anywhere. But it might even be plausible for
> std::vector:op_back() to throw, if for example it decided to
> automatically reduce its allocated size to save space, but in doing
> so manages to throw in a copy constructor?


Nope.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #4 (permalink)  
Old 11-07-2005, 09:46 AM
Calum Grant
Guest
 
Posts: n/a
Default Re: How to make the following exception-neutral

David Abrahams wrote:
> Calum Grant <calumg@onetelc.om> writes:
>
>
>>I was wondering how the following function could be made exception-
>>neutral:
>>
>> std::vector<std::string> list1, list2;
>>
>> void f(std::string const &x)
>> {
>> list1.push_back(x);
>> list2.push_back(x);
>> }

>
>
> It's already exception-neutral.
>
>
>>What if you couldn't redesign the problem and list1 and list2 needed
>>to be separate?

>
>
> I think you're looking for the answer to, "how can it be made to give
> the strong guarantee?"


Yes, you are absolutely right.

What do you think of the solution provided by the Atomic library
(http://visula.org/atomic)?

atomic::vector<std::string> list1, list2;

void f(const std::string &s)
{
atomic::transaction tr;
list1.push_back(s);
list2.push_back(s);
tr.commit();
}

This is an open-source library I am working on, which uses transactions
as a means of providing a strong exception guarantee. Your expert
feedback would be most welcome.

Calum

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #5 (permalink)  
Old 11-07-2005, 08:14 PM
Ben Hutchings
Guest
 
Posts: n/a
Default Re: How to make the following exception-neutral

Calum Grant <calumg@onetelc.om> wrote:
> I was wondering how the following function could be made exception-
> neutral:
>
> std::vector<std::string> list1, list2;
>
> void f(std::string const &x)
> {
> list1.push_back(x);
> list2.push_back(x);
> }
>
> What if you couldn't redesign the problem and list1 and list2 needed to
> be separate?
>
> Is there any way for f() to be guaranteed exception-neutral (by the
> standard), and efficient (i.e. O(1))?? The only approaches I can think
> of involve a pop_back() (which is not guaranteed by the standard), or a
> copy, which is not efficient.


Have a look at 23.1/10. This guarantees that pop_back() won't throw
and push_back() is strongly exception-safe (i.e. if it throws it
doesn't change the container). This pararaph refers to exceptions (no
pun intended) for vector in 23.2.4.3, but those are for the insert and
erase members which in general may need to call copy-assignment
operators for following elements. pop_back and push_back obviously
never do that.

<snip>
> Which is best?


Clearly f2, as it is both safe and efficient.

> Is it safe to even assume that std::vector:ush_back() is
> exception-neutral?


Yes.

> Any sane implementation would be, but I don't see it
> documented anywhere. But it might even be plausible for
> std::vector:op_back() to throw, if for example it decided to
> automatically reduce its allocated size to save space, but in doing so
> manages to throw in a copy constructor?


I don't think vector implementations are allowed to reduce their
capacity.

Ben.

--
Ben Hutchings
Having problems with C++ templates? Your questions may be answered by
<http://womble.decadentplace.org.uk/c++/template-faq.html>.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
  #6 (permalink)  
Old 11-10-2005, 10:49 AM
David Abrahams
Guest
 
Posts: n/a
Default Re: How to make the following exception-neutral

Calum Grant <calumg@onetelc.om> writes:

> What do you think of the solution provided by the Atomic library
> (http://visula.org/atomic)?
>
> atomic::vector<std::string> list1, list2;
>
> void f(const std::string &s)
> {
> atomic::transaction tr;
> list1.push_back(s);
> list2.push_back(s);
> tr.commit();
> }
>
> This is an open-source library I am working on, which uses transactions
> as a means of providing a strong exception guarantee. Your expert
> feedback would be most welcome.


I guess if you can afford the 10% performance hit and you can control
all the types in use to be sure they're atomic::-enabled, it's
probably very convenient. If not, you have to step back and use
something more general and efficient like scopeguard.

--
Dave Abrahams
Boost Consulting
www.boost-consulting.com

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Reply With Quote
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are Off
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: Throwing an exception leads to termination! Arne Mertz Newsgroup comp.language.c++.moderated 6 04-04-2009 04:07 AM
Re: Throwing an exception leads to termination! Bart van Ingen Schenau Newsgroup comp.language.c++.moderated 0 04-01-2009 03:30 AM
Make easy money!! NO SCAM!! Please Read! sulliman24@gmail.com Newsgroup comp.soft-sys.sas 0 03-01-2005 10:15 PM
Ah An Easier Way To Make Money giveitatry369@msn.com Newsgroup comp.soft-sys.sas 0 02-23-2005 10:27 PM
Re: MAKE MONEY USING PAYPAL frisbee_wizard@yahoo.com Newsgroup comp.soft-sys.sas 0 01-11-2005 05:05 PM



All times are GMT. The time now is 07:31 PM.


Copyright ©2009

LinkBacks Enabled by vBSEO 3.3.0 RC2 © 2009, Crawlability, Inc.