I’ve got the following code
template<typename FUNC, typename EXECUTOR>
void foo(FUNC func, EXECUTOR executor)
{
}
struct Marker
{
Marker * const ptr;
Marker()
: ptr(this)
{
}
Marker(const Marker &rhs) = delete;
~Marker()
{
assert(this == ptr); // <----- this fails
}
};
boost::asio::awaitable<int> xxx()
{
co_return 0;
}
boost::asio::awaitable<void> test_in_coro()
{
foo(
[marker=Marker{}]() -> int
{
return 42;
},
co_await xxx() // <--- without this it works ok
);
co_return;
}
int main()
{
boost::asio::io_context ioc;
boost::asio::co_spawn(ioc, test_in_coro(), boost::asio::detached);
ioc.run();
}
template<typename FUNC, typename EXECUTOR>
void foo(FUNC func, EXECUTOR executor)
{
}
struct Marker
{
Marker * const ptr;
Marker()
: ptr(this)
{
}
Marker(const Marker &rhs) = delete;
~Marker()
{
assert(this == ptr); // <----- this fails
}
};
boost::asio::awaitable<int> xxx()
{
co_return 0;
}
boost::asio::awaitable<void> test_in_coro()
{
foo(
[marker=Marker{}]() -> int
{
return 42;
},
co_await xxx() // <--- without this it works ok
);
co_return;
}
int main()
{
boost::asio::io_context ioc;
boost::asio::co_spawn(ioc, test_in_coro(), boost::asio::detached);
ioc.run();
}
https://godbolt.org/z/rsKK4Gv7W
The assert in the destructor of Marker
fails. Moreover, I’ve checked, that ptr
is the same as in constructor, while this
differs.
Everything works fine if I awakt before calling foo
or store the lambda in a local variable.
It happens in gcc 11.x and 12.x but not in 13.x and not in clang.
Am I falling into some undefined behavior? Or maybe is it a compiler bug?