1
votes

Everething worked with online compilers, but not with Visual2019

I am creating small library and got problem with std::function. I use it because i need to pass function pointer or lamda to one of class setters, and use it in class method.

The problem is that std::function variable is NULL for all instances of class exept first, but setters were called for all. My class method calls that functions inside while(true) loop, that is in other thread, setters were called from main function and main thread.

Here are some parts of code:

place where i call function:

for (auto j = equalrange.first; j != equalrange.second; j++)
{
    j->second->draw_updater();
    if (j->second->on_update_fx != NULL)
        j->second->on_update_fx();
    else
        std::cout << "NULL\n";

setter:

void OnUpdate(const std::function<void()> fx)
    {on_update_fx = fx;};

What can cause that problem? All objects from equalrange range are not NULL

Small example:

#include <functional>
#include <future>

class MyClass {
public:
    void SetFx(std::function <void()> func) { fx = func; }
    void do_work()
    {
             ft = std::async([this] {
            while (true)
            {
                if (fx != NULL)
                    fx();
                else
                {
                    std::cout << "NULL\n";
                }
            }
             });
       
    }
private:
    std::future <void> ft;
    std::function <void()> fx;
};
int main()
{
    int c = 10;
    MyClass a;
    MyClass b;
    a.SetFx([&]() {std::cout << "a " << std::endl; });
    b.SetFx([&]() {std::cout << "b " << std::endl; });
    a.do_work();
    b.do_work();
}
2
It would help if you could provide a minimal, reproducible example.Dennis Sparrow
Worked great on my machine. But I had to add lots of code to test it out. Could be a bug in the code not provided.Eljay
@DennisSparrow i`ve posted it in my edit, sorry for i have not posted it earlierOlexy
@paler123 it is strange, probably bug in my compiler, ewerething realy works with online compilersOlexy

2 Answers

1
votes

It's not a compiler bug (and can be reproduced by a lot of compilers...). At least your example is not correct. There you're potentially running into undefined behavior since you capture pure (potentially gone) this within the std::async call. If you debug the destruction behavior of your class, you will at least sporadically observe gone objects before the functor calls are applied. Capture the objects you need by value or ensure the objects' existence during all calls to them.

If your example is solely not correct, but you're sure your actual productive code is, please provide the relevant parts with that lifetime info of the involved objects at least.

-2
votes

Works fine with other compilers, there is probably bug in visual2019 compiler, compilation settings were default.