C++: Smart pointers and returning "nothing"

Barnaby W. Füi

Elite Member
Aug 14, 2001
12,343
0
0
I'm using boost smart pointers specifically, but one thing I can't seem to figure out is how to have a function return "nothing".

e.g. normally you'd do something like:

Foo * find_a_foo() {

Foo * foo;
if((foo = look_for_a_foo_somehow())) return foo;

return NULL; // found nothing, now they can check the result of this function for truth and if this NULL is returned, it will evaluate to false

}

But with smart pointers:

shared_ptr<Foo> find_a_foo() {

shared_ptr<Foo> foo;
if((foo = look_for_a_foo_somehow())) return foo;

return ????; // what can I return to indicate "nothing"? "(shared_ptr<Foo>) 0" doesn't work, NULL doesn't work, tried a few other things as well..

}
 

Barnaby W. Füi

Elite Member
Aug 14, 2001
12,343
0
0
Got it. Just initialize one and don't put anything in it.

shared_ptr<Foo> blah;
return blah;

So simple. :)

edit: HAH! I should have heeded the second part of my sig in the first place.
 

Kntx

Platinum Member
Dec 11, 2000
2,270
0
71
Originally posted by: BingBongWongFooey
Got it. Just initialize one and don't put anything in it.

shared_ptr<Foo> blah;
return blah;

So simple. :)

edit: HAH! I should have heeded the second part of my sig in the first place.

Although that works, I'd recommend you initialize it to 0.

shared_ptr<foo> findafoo()
{
shared_ptr<foo> blah = 0;
blah = lookforafoo();
return blah;
}

The reason being, what you are doing now has undefined behavior. That is... the results are not guaranteed. So even though it works properly now (or seems to) sometime in the future your program might crash, and the bug will be very hard to track down.

 

Barnaby W. Füi

Elite Member
Aug 14, 2001
12,343
0
0
Didn't work:

client.cc: In function `boost::shared_ptr<Client> find_client(long unsigned int, int)':
client.cc:100: error: conversion from `int' to non-scalar type `boost::shared_ptr<Client>' requested

using (Client)0 instead of 0 doesn't work either.

http://www.jelovic.com/articles/cpp_without_memory_errors_slides.htm

What would be the characteristics of such a smart pointer?

1. It always points either to a valid allocated object or is NULL.

The docs for boost's smart pointers don't seem to discuss this issue specifically but the constructor has this signature:

explicit scoped_ptr(T * p = 0);

Constructs a scoped_ptr, storing a copy of p, which must have been allocated via a C++ new expression or be 0. T is not required be a complete type. See the smart pointer common requirements.

So I'm pretty sure what I'm doing is correct.

edit

did a small test.

#include <iostream>
#include <boost/shared_ptr.hpp>
using boost::shared_ptr;
using namespace std;

int main() {
shared_ptr<int> s;
if(s) cerr << "you can dereference it!" << endl;
else cerr << "you can't!" << endl;
cout << (int)*s << endl;
cout << *s << endl;
return 0;
}

And when I run it:

you can't!
a.out: /usr/include/boost/shared_ptr.hpp:232: typename boost::Detail::shared_ptr_traits<T>::reference boost::shared_ptr<T>::eek:perator*() const [with T = int]: Assertion `px != 0' failed.
Aborted
 

ElDonAntonio

Senior member
Aug 4, 2001
967
0
0
did you try in release build? just to make sure...in VC++ all undefined variables are initialized to 0 when compiling in debug, but not in release.
Although if the ptr is set to 0 in the constructor, it's foolproof.
 

Barnaby W. Füi

Elite Member
Aug 14, 2001
12,343
0
0
Originally posted by: ElDonAntonio
did you try in release build? just to make sure...in VC++ all undefined variables are initialized to 0 when compiling in debug, but not in release.
Although if the ptr is set to 0 in the constructor, it's foolproof.

I'm using gcc, and compiling with -02 (which means variables are not automatically zeroed when initialized)