
Hi, Can you please tell me how can I return a 'null' smart pointer? typedef shared_ptr<MyA> MyAPtr; typedef vector<MyAPtr> MyAVector; For example,I have this code, which return NULL in an error situation: MyAPtr myfunction(MyAVector& v, int size) { if (index < v.size()) { return v[index]; } else { // how can I return NULL here? } } How can I achieve that when I use boost smart pointer? Thank you for any tip.

At 4:43 PM -0500 7/14/08, Meryl Silverburgh wrote:
Hi,
Can you please tell me how can I return a 'null' smart pointer?
typedef shared_ptr<MyA> MyAPtr; typedef vector<MyAPtr> MyAVector;
For example,I have this code, which return NULL in an error situation:
MyAPtr myfunction(MyAVector& v, int size) { if (index < v.size()) { return v[index]; } else { // how can I return NULL here? } }
How can I achieve that when I use boost smart pointer?
I suggest that you throw an exception here, rather than returning some bogus value. -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.

Marshall Clow skrev:
At 4:43 PM -0500 7/14/08, Meryl Silverburgh wrote:
Hi,
Can you please tell me how can I return a 'null' smart pointer?
typedef shared_ptr<MyA> MyAPtr; typedef vector<MyAPtr> MyAVector;
For example,I have this code, which return NULL in an error situation:
MyAPtr myfunction(MyAVector& v, int size) { if (index < v.size()) { return v[index]; } else { // how can I return NULL here? } }
How can I achieve that when I use boost smart pointer?
I suggest that you throw an exception here, rather than returning some bogus value.
I concur, but I suggest you simply add a precondition: assert( index < v.size() ) -Thorsten

On Tue, Jul 15, 2008 at 3:26 AM, Thorsten Ottosen <thorsten.ottosen@dezide.com> wrote:
Marshall Clow skrev:
At 4:43 PM -0500 7/14/08, Meryl Silverburgh wrote:
Hi,
Can you please tell me how can I return a 'null' smart pointer?
typedef shared_ptr<MyA> MyAPtr; typedef vector<MyAPtr> MyAVector;
For example,I have this code, which return NULL in an error situation:
MyAPtr myfunction(MyAVector& v, int size) { if (index < v.size()) { return v[index]; } else { // how can I return NULL here? } }
How can I achieve that when I use boost smart pointer?
I suggest that you throw an exception here, rather than returning some bogus value.
You mention "I suggest that you throw an exception here, rather than returning some bogus value." So when I do this: shared_ptr<MyClass> aPtr; and then I check for 'null' , like this: if (aPtr == NULL) { // will it return true here? }
I concur, but I suggest you simply add a precondition:
assert( index < v.size() )
-Thorsten _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users

Marshall Clow (14.7.2008 23:50):
At 4:43 PM -0500 7/14/08, Meryl Silverburgh wrote:
Hi,
Can you please tell me how can I return a 'null' smart pointer?
typedef shared_ptr<MyA> MyAPtr; typedef vector<MyAPtr> MyAVector;
For example,I have this code, which return NULL in an error situation:
MyAPtr myfunction(MyAVector& v, int size) { if (index < v.size()) { return v[index]; } else { // how can I return NULL here? } }
How can I achieve that when I use boost smart pointer?
I suggest that you throw an exception here, rather than returning some bogus value.
What is so bad in general about returning uninitialized smart pointers? Is that more costly than throwing an exception? I mean, there is even some support for testing a smart pointer for validity built into shared_ptr, so why not use it where appropriate? Cheers, Filip

Marshall Clow (14.7.2008 23:50):
At 4:43 PM -0500 7/14/08, Meryl Silverburgh wrote:
Hi,
Can you please tell me how can I return a 'null' smart pointer?
typedef shared_ptr<MyA> MyAPtr; typedef vector<MyAPtr> MyAVector;
For example,I have this code, which return NULL in an error situation:
MyAPtr myfunction(MyAVector& v, int size) { if (index < v.size()) { return v[index]; } else { // how can I return NULL here? } }
How can I achieve that when I use boost smart pointer?
I suggest that you throw an exception here, rather than returning some bogus value.
What is so bad in general about returning uninitialized smart pointers? Is that more costly than throwing an exception? I mean, there is even some support for testing a smart pointer for validity built into shared_ptr, so why not use it where appropriate?
The only problem with returning a null pointer, or -1, or whatever in case of error is that it's easy to ignore at the calling scope, so the upper layers would not even know the error occurred. Exception, on the other hand, propagates up the stack enforcing more structured error handling. -- Nikolai

What is so bad in general about returning uninitialized smart pointers? Is that more costly than throwing an exception? I mean, there is even some support for testing a smart pointer for validity built into shared_ptr, so why not use it where appropriate?
The only problem with returning a null pointer, or -1, or whatever in case of error is that it's easy to ignore at the calling scope, so the upper layers would not even know the error occurred. Exception, on the other hand, propagates up the stack enforcing more structured error handling.
I agree, but only if the case is an error. In my application, I have several places where the "null" value is a regular result. That's what I meant by saying "where appropriate". Cheers, Filip

Nikolai N Fetissov <nikolai-boost <at> fetissov.org> writes:
What is so bad in general about returning uninitialized smart pointers? Is that more costly than throwing an exception? I think it's even the other way around.
I mean, there is even some support for testing a smart pointer for validity built into shared_ptr, so why not use it where appropriate? I think this is approriate, as u write in your email. For example finding customer orders which need not exist in an order table, is not an exceptional case and can be signalled with a NULL ptr.
The only problem with returning a null pointer, or -1, or whatever in case of error is that it's easy to ignore at the calling scope, so the upper layers would not even know the error occurred. Exception, on the other hand, propagates up the stack enforcing more structured error handling. Yes but not handling exceptions is fatal for your applications which can be a good thing if the case would corrupt your system anyway, or a bad thing if no serious bad things happen. If every Space Shuttle would crash on every fault, there would be no new austronauts in the USA.
Sutter has made a guideline for when to use exceptions and when not ("When and How to Use Exceptions", http://www.ddj.org/cpp/184401836). By using this guideline, programmers actually have to deal with two strategies instead of one, not to mention that writing excpetion safe code (without leaks) is very hard. If you get stuck you can always buy his books :) Then again there was someone who wrote that writing exception safe code is hard because dealing with errors is hard. So maybe the problem may be more fundamental.

gast128 <gast128@hotmail.com> wrote:
Sutter has made a guideline for when to use exceptions and when not ("When and How to Use Exceptions", http://www.ddj.org/cpp/184401836). By using this guideline, programmers actually have to deal with two strategies instead of one, not to mention that writing excpetion safe code (without leaks) is very hard. If you get stuck you can always buy his books :)
Actually, having read all of Bruce's books, and having talked to him at a couple of conferences, I find that writing exception safe code is quite simple - once you have embraced RAII everywhere. You do have to think about exception safety, but for most routines that thinking boils down to "What happens if something throws here? Um, .... nothing bad.", since RAII ensures that no locals leak, and I can look at the global/parameter cases quickly. I find it also leads to simple, easy to write (and understand code). -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.

Marshall Clow <marshall <at> idio.com> writes:
gast128 <gast128 <at> hotmail.com> wrote:
Sutter has made a guideline for when to use exceptions and when not ("When
and
How to Use Exceptions", http://www.ddj.org/cpp/184401836). By using this guideline, programmers actually have to deal with two strategies instead of one, not to mention that writing excpetion safe code (without leaks) is very hard. If you get stuck you can always buy his books :)
Actually, having read all of Bruce's books Eh, isn't his name Herb...
, and having talked to him at a couple of conferences, I find that writing exception safe code is quite simple - once you have embraced RAII everywhere. You do have to think about exception safety, but for most routines that thinking boils down to "What happens if something throws here? Um, .... nothing bad.", since RAII ensures that no locals leak, and I can look at the global/parameter cases quickly. Not sure about that. I think you probably have to wrap every raw pointer in a smart pointer or ending up having try / catch everywhere. Writing everywhere try / catch doesn't improve the readability imo (which is also depreciated by people). Item 17-23 and item 29 of more exceptional c++ are all about case where exceptions occur, none of them are trivial (for me at least).
I find it also leads to simple, easy to write (and understand code). Sure? What if you make a pool of available devices like (COM ports) and they throw when not available (which btw raises the question if this an exceptional case or just common):
std::vector<Device*> v; for (int n = 0; n < nSize; ++n) { try { Device* pDevice = new Device(n); v.push_back(pDevice); } catch (...) { //not available } } is this more readable then: for (int n = 0; n < nSize; ++n) { std::auto_ptr<Device> ptrDevice(new Device(n)); if (ptrDevice->IsOk()) { v.push_back(ptrDevice.Release()); } } Probably I can predict your answer. If you write deep nested functions with clear entry points, these exception can really improve the code, but then you are using them as a pimped 'goto' statement, which was not the intention.

Marshall Clow <marshall <at> idio.com> writes:
gast128 <gast128 <at> hotmail.com> wrote:
Sutter has made a guideline for when to use exceptions and when not ("When
and
How to Use Exceptions", http://www.ddj.org/cpp/184401836). By using this guideline, programmers actually have to deal with two strategies instead of one, not to mention that writing excpetion safe code (without leaks) is very hard. If you get stuck you can always buy his books :)
Actually, having read all of Bruce's books Eh, isn't his name Herb...
D'oh! ;-) [ OK - I don't know who I which "Bruce" I was thinking of ]
, and having talked to him at a couple of conferences, I find that writing exception safe code is quite simple - once you have embraced RAII everywhere. You do have to think about exception safety, but for most routines that thinking boils down to "What happens if something throws here? Um, .... nothing bad.", since RAII ensures that no locals leak, and I can look at the global/parameter cases quickly. Not sure about that. I think you probably have to wrap every raw pointer in a smart pointer or ending up having try / catch everywhere.
I think that's what I said: "Embraced RAII everywhere". That means that every resource that you acquire/allocate gets wrapped in something that will automatically close/release/delete it when it goes out of scope. This simplifies code for both the exceptional and non-exceptional case.
Writing everywhere try / catch doesn't improve the readability imo (which is also depreciated by people). Item 17-23 and item 29 of more exceptional c++ are all about case where exceptions occur, none of them are trivial (for me at least).
I find it also leads to simple, easy to write (and understand code).
Sure? What if you make a pool of available devices like (COM ports) and they throw when not available (which btw raises the question if this an exceptional case or just common):
std::vector<Device*> v;
for (int n = 0; n < nSize; ++n) { try { Device* pDevice = new Device(n); v.push_back(pDevice); } catch (...) { //not available } }
is this more readable then:
for (int n = 0; n < nSize; ++n) { std::auto_ptr<Device> ptrDevice(new Device(n)); if (ptrDevice->IsOk()) { v.push_back(ptrDevice.Release()); } }
I note that you're not handling failures of the "new Device (n)" call. ;-) [ or the "push_back", either ] Of course anyone can make up examples where exceptions are good/bad, so I won't bore you with mine.
Probably I can predict your answer. If you write deep nested functions with clear entry points, these exception can really improve the code, but then you are using them as a pimped 'goto' statement, which was not the intention.
-- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.

At 6:21 AM -0700 7/17/08, Marshall Clow wrote:
Of course anyone can make up examples where exceptions are good/bad, so I won't bore you with mine.
Re-reading this, I realized that this could be read as saying that gast128's example was boring. That was not my intent - rather that "dueling examples" would get boring. P.S. Bruce Sutter was a baseball player, and I think that's where I in my memory I grabbed the wrong first name from. ;-) -- -- Marshall Marshall Clow Idio Software <mailto:marshall@idio.com> It is by caffeine alone I set my mind in motion. It is by the beans of Java that thoughts acquire speed, the hands acquire shaking, the shaking becomes a warning. It is by caffeine alone I set my mind in motion.

-------------------------------------------------- From: "gast128" <gast128@hotmail.com> Sent: Wednesday, July 16, 2008 3:25 PM To: <boost-users@lists.boost.org> Subject: Re: [Boost-users] how can I return a 'null' smart pointer?
Nikolai N Fetissov <nikolai-boost <at> fetissov.org> writes:
What is so bad in general about returning uninitialized smart pointers? Is that more costly than throwing an exception? I think it's even the other way around.
I mean, there is even some support for testing a smart pointer for validity built into shared_ptr, so why not use it where appropriate? I think this is approriate, as u write in your email. For example finding customer orders which need not exist in an order table, is not an exceptional case and can be signalled with a NULL ptr.
A function like you mention (maybe vector<OrderPtr> Customer::GetUnfulfilledOrders( void ); ) could return an vector or custom collection with 0 elements, however with a function like OrderPtr Customer::GetOrder(int ordern); to me it feels natural to throw an exception. Sure shared_ptr does have a mechanism for validity checking but if you forget to validate it and dereference the pointer then you have an exceptional condition on your hands. Is it easier to check the pointer for validity or wrap the block in a try {} catch{}? Personally I would probably have the block in a try-catch already and in the circumstances that we are talking about (getting order data for a customer) catching an exception is an extremely small amount of overhead.
The only problem with returning a null pointer, or -1, or whatever in case of error is that it's easy to ignore at the calling scope, so the upper layers would not even know the error occurred. Exception, on the other hand, propagates up the stack enforcing more structured error handling. Yes but not handling exceptions is fatal for your applications which can be a good thing if the case would corrupt your system anyway, or a bad thing if no serious bad things happen. If every Space Shuttle would crash on every fault, there would be no new austronauts in the USA.
Sutter has made a guideline for when to use exceptions and when not ("When and How to Use Exceptions", http://www.ddj.org/cpp/184401836). By using this guideline, programmers actually have to deal with two strategies instead of one, not to mention that writing excpetion safe code (without leaks) is very hard. If you get stuck you can always buy his books :)
I think Herb's argument for using exceptions instead of error codes is very , as he puts it, persuasive. Isn't a call to find a customer's orders coming back with nothing an error that you are signaling with a null pointer? It surely isn't a successful finishing state.

On Jul 16, 2008, at 6:24 PM, Joshua Perry wrote:
A function like you mention (maybe vector<OrderPtr> Customer::GetUnfulfilledOrders( void ); ) could return an vector or custom collection with 0 elements, however with a function like OrderPtr Customer::GetOrder(int ordern); to me it feels natural to throw an exception.
I think this is more like a find function, so you could return an iterator to the appropriate element, and return a one-past-the-end iterator if the order number wasn't found. In your example, you're effectively trying to run a find and then return a dereferenced result. I guess that you are trying to hide any container-ness about the order system, so either returning an order reference or throwing is probably better, but only if you expect the user to never try entering invalid order numbers. If entering invalid numbers is a standard occurrence (pre-checking is too hard and/or not expected), then it wouldn't be a post-condition violation, and a null-pointer should be returned instead. -- Daryle Walker Mac, Internet, and Video Game Junkie darylew AT hotmail DOT com
participants (10)
-
Daryle Walker
-
Filip Konvička
-
gast128
-
Joshua Perry
-
Marshall Clow
-
Meryl Silverburgh
-
Nat Goodspeed
-
Nikolai N Fetissov
-
Steven Watanabe
-
Thorsten Ottosen