0

Currently I have a own version of a linked list in a std::unordered_map<key,List<shared_ptr<t>>> (where t is some type). I insert stuff like so:

void addTo(const Key &key, t* ptr)
{
    if(ptr==nullptr||ptr==NULL){
       throw "this is not a real exception that I am using"
   }
    try
    {
        this->getList(key).addNew(std::shared_ptr<t>(ptr));
    }
    catch(std::out_of_range ex)
    {
        this->addList(key,(std::shared_ptr<t>(ptr));
    }
}

However, I recently noticed that when the getList throws a out_of_range exception (which it always does if the map doesnt have a key like that in it) then the ptr gets deleted. Now it would make sense if the shared_ptr was created before getList is called, but why would that be the case?

I have verfied this by simply seperating this->getList and addNew like so:

const List<shared_ptr<t>> l& = this->getList(key);
l.addNew(etc etc);

When writing it like this, nothing happens to the pointer.

This leads me to conclude that the shared_ptr gets created first, which would mean that c++ processes instancing first? To me that doesnt make a while lot of sense.

What are the exact rules for the order in which c++ does these kind of statements and why is it not instancing the shared_ptr AFTER ->getList (what is the reason for doing it differently)?

MoustacheSpy
  • 743
  • 1
  • 6
  • 27
  • 1
    The idea of using smart pointers it give an answer with code instead of documentation to the question "Who _owns_ that resource?". In order to use smart pointers efficiently, you need to learn about resource property managment. Take some time to do so. – YSC Mar 28 '18 at 11:48
  • The guy who creates the object that ptr points to should also create the shared_ptr and deliver it to your addTo(). Use shared_ptr's "everywhere" or don't use them at all. You always need to keep at least one shared_ptr to the object alive. – juzzlin Mar 28 '18 at 11:56
  • 1
    If you're wondering about evaluation order and sequencing, then see e.g. [this evaluation order and sequencing reference](http://en.cppreference.com/w/cpp/language/eval_order), as well as [this detailed answer](https://stackoverflow.com/a/4176333/440558) (with [this follow up for C++11](https://stackoverflow.com/a/4183735/440558) and later). – Some programmer dude Mar 28 '18 at 12:06
  • @Someprogrammerdude Thanks for giving me the first actual in context comment instead of making snarky comments about code of which they miss half the context. – MoustacheSpy Mar 28 '18 at 14:06

1 Answers1

4

Order of execution between std::shared_ptr<t>(ptr) and getList(key) is unspecified in:

this->getList(key).addNew(std::shared_ptr<t>(ptr));

It might change from one compiler to other or even from one call to another.

C++17 adds more rules for evaluation order; you should have your expected order of evaluation guaranteed since this version.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Jarod42
  • 203,559
  • 14
  • 181
  • 302