Forum Replies Created
-
AuthorPosts
-
::
A spinlock may be useful when you only wait for a short period of time because the sleeping of the mutex is expensive. Usually, a mutex spins for a short time and then falls asleep. std::mutex is only a wrapper around the OS mutex. This means it is probably a pthread mutex on Unix/Linux. You can access the underlying mutex by calling std::mutex::native_handle.
25. January 2024 at 18:09 in reply to: Fetch multiply implementation in Meeting C++ presentation #632951::Here is your modified await_suspend call.
void await_suspend(std::coroutine_handle<> h) { auto outerThread = std::jthread([h]() { h.resume();}); }
You use a jthread. The jthread automatically joins in its destructor if still joinable. This means, your await_suspend call is blocking.
Additionally, you don’t have a handle to the thread. You can, for example, not cooperatively interrupt it.
::The function await_suspend handles the suspension of the coroutine. await_suspend is the crucial function of the Awaiter. It can have the following return types:
- void: the control flow immediately returns to the caller. The coroutine remains suspended.
- bool:
- true: the control flow immediately returns to the caller
- false: the coroutine is resumed
- std::coroutine_handle<>:
- if it returns a coroutine handle coroHandle of another coroutine, this coroutine is resumed: coroHandle.resume(). This strategy is called symmetric transfer.
- std::noop_coroutine: no coroutine is resumed. Equivalent to returning true.
In both the example and in the case where we don’t call handle.resume() in await_suspend like here the coroutines get destroyed thanks to the destructor of Job and there are no leaks right?
Right.
In the example, I think it would be better to use the name MySuspendSometimes instead of MySuspendAlways.
You are right. It only sometimes suspends when await_ready return true.
::- When I have three iterations in the coroutine and four iterations in main, I get the last value repeated and no error
You resume final_suspend. This is undefined behavior.
- When I have two iterations in the coroutine and four iterations in main, I get an error
There is nothing left to resume. The coroutine already ended.
::There is an excellent about distributing modules on CppCon 2023: C++20 Modules: The Packaging and Binary Redistribution Story by Luis Caro Campos
::std::cout << '\n'; std::atomic<std::shared_ptr<std::string>> sharString( std::make_shared<std::string>("Zero")); std::thread t1([&sharString]{ sharString.store(std::make_shared<std::string>(*sharString.load() + "One")); }); std::thread t2([&sharString]{ sharString.store(std::make_shared<std::string>(*sharString.load() + "Two")); }); std::thread t3([&sharString]{ sharString.store(std::make_shared<std::string>(*sharString.load() +"Three")); }); std::thread t4([&sharString]{ sharString.store(std::make_shared<std::string>(*sharString.load() +"Four")); }); std::thread t5([&sharString]{ sharString.store(std::make_shared<std::string>(*sharString.load() +"Five")); });
::When you apply multiple inheritance, the base classes should be orthogonal. Said that, this example is crazy because both base classes provide a pure virtual member function display. I cannot find anything in the C++ standard, but I assume that the program is correct. You essentially override both pure virtual member functions.
I modified the program and added a display function to Derived:
#include <iostream> class GrandGrandParent { public: virtual void display() = 0; }; class GrandParent : public GrandGrandParent { }; class human { public: virtual void display() = 0; }; class Parent : public GrandParent, public human { public: // Both parent class has method with same name display. We have overriden the function in this class. // Which function is getting overriden ? Can you please provide some more insight how static(Parent*P) and dynamic type(new Derived()) working here void display() override { std::cout << "Derived"; } }; class Derived : public Parent { void display() override { std::cout << "Derived display"; } }; int main() { Parent *p = new Derived(); p->display(); // Derived }
The static type of Parent *p = new Derived() is Parent but the dynamic Derived. The static type determines the access specifiers. Consequentially, display in Derived can be private.
15. November 2023 at 09:53 in reply to: Difference between GCC and MSVC for floating non-type template parameters #632028::Interestingly, when you use a constexpr function in between, the GCC and MSVC apply the necessary conversions: https://godbolt.org/z/d3jM6oaeP
template <double d> auto acceptOnlyDouble() { return d; } constexpr double ToDouble(double param) { return param; } int main() { const auto xf_double88 = acceptOnlyDouble<-5.123456788>(); const auto xf_double89 = acceptOnlyDouble<-5.123456789>(); const auto xf_float = acceptOnlyDouble<ToDouble(-9.48f)>(); const auto xf_long = acceptOnlyDouble<ToDouble(-20L)>(); }
Finally, I asked Jorg Brown, author of the proposal P1714: NTTP are incomplete without float, double, and long double! (Revision 1).
He said: Anyway, to answer your question, I think MSVC is doing the right thing here. I’ll check with a friend to be sure…
-
AuthorPosts