5 ms·
Could someone please explain why you'd put nodiscard on a constructor? I'm a bit confused as to when that's needed.
by mehrdadn 7y ago
Could someone please explain why you'd put nodiscard on a constructor? I'm a bit confused as to when that's needed.
- wyldfire 7y agoIf it's constructed as a temporary rvalue but never stored or passed as an argument, I think there's places where the compiler can elide the code entirely. Whereas you might prefer it have the system side effects associated with construction and destruction.
- mehrdadn 7y agoSo it's for copy/move-constructors only?
- wyldfire 7y agoNo. Sorry for being unclear. [1] is a great video that covers a lot of good stuff in particular this usability bug. It's worth watching in its entirety. If you don't want to sit through the video, here's the broken code in question: void Obj::update() noexcept { unique_lock<mutex>(m_mutex); do_the_mutation(); } "unique_lock<mutex>(m_mutex);" has no effect, but you might mistakenly think that this will block on m_mutex. Labeling unique_lock's constructor as [[nodiscard]] would force you to think twice. See [2] for more details. [1] https://youtu.be/lkgszkPnV8g?t=1767 https://youtu.be/lkgszkPnV8g?t=1767 [2] http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1771r0.pdf http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p177...
- mehrdadn 7y agoAhh, that makes sense! On my phone at the moment but will check out the video too, thanks!
- deleted 7y ago[deleted]
- thestoicattack 7y agoTo avoid this insidious bug: std::lock_guard<std::mutex>(m); // guard is immediately thrown away versus the correct std::lock_guard<std::mutex> g(m); // hold mutex til end of scope
- dgellow 7y agoNote for people who don’t see the difference: if a guard doesn’t have a name, it won’t survive until the end of the scope, thus doesn’t guard anything.
- deleted 7y ago[deleted]
- deleted 7y ago[deleted]
- ynfnehf 7y agoI might be wrong here, but I think that the first one is a declaration of a guard with the name m using the default constructor. The same way that int (a); and int a; are equivalent. So the guard should remain until end of scope, but won't guard anything.
- clappski 7y agolock_guard doesn’t have a default ctor, you have to pass a mutex (or presumably invoke a move ctor, but I can’t see one on cppref).
- bstamour 7y agoLock guard has no default constructor, so the line will in fact materialize a temporary lock guard around the mutex m, then throw it away at the semi-colon, thus locking nothing.
- qorrect 7y agoAfter not using C++ for 15+ years , looking at it now makes my eyes bleed.
- mehrdadn 7y agoThat's how I felt looking at C++17 deduction guides, and that's even though I've actually been using C++. If you haven't seen them yet you should check them out ;)
- deleted 7y ago[deleted]
- DoofusOfDeath 7y agoI use it everyday, and I'm still very eager to stop using it due to its growing complexity. I'm trying to gradually replace C++ with Rust as my primary language, but it's still a lot easier to get a well-paying job in C++ than in Rust.
- otabdeveloper2 7y agoRust is both more complex and uglier than modern C++. If your complaint is having to learn new stuff, then Rust isn't the solution.
- andrekandre 7y agoi’m not disagreeing with you (i’m learning rust, so don’t have a strong opinion yet) but am curious how you feel that way?
- w0utert 7y agoUsing modern C++ everyday, that’s how I feel looking at C++98 code ;-)