4 ms·
> By far the best element of C++ that a lot of other languages lack is const and const-correctness. Add to that volatile-correctness... which most people aren'
by mehrdadn 7y ago
> By far the best element of C++ that a lot of other languages lack is const and const-correctness.
Add to that volatile-correctness... which most people aren't even aware of. http://www.drdobbs.com/cpp/volatile-the-multithreaded-programmers-b/184403766 http://www.drdobbs.com/cpp/volatile-the-multithreaded-progra...
- aarongolliver 7y agoThis article is nearly 2 decades old and gives very bad advice for multithreaded c++ programming. To a first approximation, volatile should never be used for multithreading safety.
- mehrdadn 7y agoThat 2-decade-old article took some 5+ pages to thoroughly explain its ideas. Turns out it was (and still is) pretty compelling, and the changes in these past 2 decades don't really affect what it's saying. You, who've surely carefully read the article, understood it in its entirety, and played around with the notion to get a feel for its upsides and downsides, very insightfully reduced it all down to "very bad advice" with zero elaboration. You find that compelling? I would be careful with those "first-order approximations".
- ori_b 7y agoVolatile is not a memory barrier. Different threads can observe reordered accesses regardless of volatile. There's a reason that it's been proposed for removal (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p1152r0.html http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2018/p115...)
- mehrdadn 7y agoWhere did you see the article claim it was a memory barrier?
- aarongolliver 7y agoIt doesn't say it's a memory barrier, but it absolutely has to be for the code to work. I agree I should be careful with "first-order approximations", but honestly I was being gentle because I do love drdobbs. But all of the things it talked about have been replaced with things that aren't broken in subtle and hard to debug way. Volatile simply cannot be used a general purpose, portable, synchronization primitive.
- mehrdadn 7y ago> It doesn't say it's a memory barrier, but it absolutely has to be for the code to work. No, it doesn't say it because it's not trying to make the point that you assume it's trying to make. Honest question: did you fully read and digest the article before commenting? If so, tell me on precisely which line you saw a lack of a memory barrier causing a problem (describe the race condition & bug you found) and explain how exactly you found that to undermine the point of the article.
- deleted 7y ago[deleted]
- deleted 7y ago[deleted]
- BeeOnRope 7y agoYou don't even need to read the whole article to see the GP's point: the very first example with flag_ is concurrent, unsynchronized access to a shared volatile, and the article promotes it as "the right way". Yes, it goes on to elaborate on a basically unrelated use of volatile to control access to member functions on classes, which deserves a separate discussion - but you don't even need to get past the first few paragraphs to see that it promulgates the idea that broken makes concurrent access safe. It doesn't.
- ori_b 7y agoThe code in the article requires memory barriers. It doesn't have them. It's broken code. The author is using volatile as though it implied a barrier.
- BeeOnRope 7y agoDespite that it was written by Alexandrescu, I can say that without a doubt this 2001 article doesn't represent the current state of thought around MT programming and volatile. I'd think of it more as a historical artifact than anything.
- mehrdadn 7y agoThe fact that it doesn't doesn't mean it shouldn't be. It's a damn useful method, it just didn't become popular.
- BeeOnRope 7y agoIt shouldn't be. The stuff the article recommends is straight up UB in modern C++. Volatile has never been specified to work properly with threads, but before C++11 when there was no alternative, some limited use in that context, preferably hidden away from the casual user, may have been acceptable. Recommending these techniques today, however, makes no sense.
- mehrdadn 7y agoIt should be. The stuff you're taking about is not the same stuff I'm talking about. There's nothing UB about the locking pointer pattern and how it uses volatile. Read the article in full. It has a specific thesis that is just as valid today as it was 20 years ago, and that thesis is NOT the 2001 malpractice you're talking about.
- BeeOnRope 7y agoYes the locking pointer pattern shown there is also UB because it is UB to define something as volatile and then cast away the volatile and use it, which is the core of that technique. Yes, it's not UB in the race sense, because he is using mutxes everywhere there and just sort of overloading the volatile qualifier to catch member function calls outside the lock. In addition to being UB, it's weird - why not just escapsulate the object itself inside a class that only hands out access under control of a lock? That is, why have the volatile object passed in from the outside if you will never legally access the object? The very premise of this article, that volatile is for concurrently modified objects across threads is false in modern C++ - and the very first example is a faulty use of volatile under the assumption that unguarded concurrent volatile access is safe.