- "Modern C++" != "New(est) Standard" - 2 Updates
- Should you use constexpr by default? - 8 Updates
- constexpr function for identifying compile-time constants - 1 Update
| woodbrian77@gmail.com: Aug 25 11:08AM -0700 On Friday, August 24, 2018 at 1:31:03 AM UTC-5, Öö Tiib wrote: > and ridiculously useful. The union was always unsafe and usage of > raw or unique_ptr to represent little, possibly missing value was > so sadly inefficient. I think variant is kind of useful, but am not as convinced about optional. I've considered several times using a vector of optional rather than a vector of unique_ptr here: https://github.com/Ebenezer-group/onwards/blob/master/src/cmw/tiers/cmwA.cc , but optional: increases the size of my text segment by about 2% and results in more expensive moves than unique_ptr. The benefit of optional would be to avoid the heap allocation and deallocation. I avoid the heap in general, but in this case think the advantages of unique_ptr are worth it, especially if the size of my type grows over time leading to even bigger text segments and more expensive moves. I'm not a big proponent of unique_ptr, but in this case I find it helpful. Brian Ebenezer Enterprises http://webEbenezer.net |
| "Öö Tiib" <ootiib@hot.ee>: Aug 25 02:29PM -0700 > , but optional: > increases the size of my text segment by about 2% and > results in more expensive moves than unique_ptr. I can't imagine how you measured? Optional means additional bool, when unique_ptr means additional pointer, additional indirection and additional dynamic allocation/deallocation. The situations may certainly vary but can't be that by that lot. > segments and more expensive moves. > I'm not a big proponent of unique_ptr, but in this case I find > it helpful. The unique_ptr is useful when the component is polymorphic. Optional can't be polymorphic. It is also easy to see how unique_ptr can provide storage performance advantage when the component is often missing (rarely present) but how it can provide better speed performance? Can you provide a cite or benchmark? In general what is currently pricey is not memory amount, nor throughput but it is latency. Optionals are local and that always means less cache misses and better latency. |
| Richard Damon <Richard@Damon-Family.org>: Aug 24 07:31PM -0400 On 8/24/18 3:21 PM, Daniel wrote: > size_t size() const; > neither you (nor the compiler) can conclude anything about whether size() const is or is not mutating. Whether the data member is stored in size_t size_ or in size_t* size_ is an implementation detail that is neither here nor there. This greatly reduces the value of the const qualifier, to the point where it's merely suggestive, nothing more. > Daniel const member functions are simply not allowed to modify (non-mutable) members IN the structure. Data in affiliated structures is not protected. Yes, this says that 'const' is not a total concept of the 'value' of a structure, but doesn't make it worthless, just maybe worth less than it could be. Whether the constness of the object should pass to the things it points to is very much dependent on context. I suppose it might be useful to have some attribute on a pointer to make the constness of the data pointed inherit from the constness of the object the pointer is in to allow it to be specified on a case by case basis. |
| Richard Damon <Richard@Damon-Family.org>: Aug 24 07:35PM -0400 On 8/24/18 10:21 AM, bitrex wrote: > or something. > Don't see any reason intrinsically it couldn't be that way other than > there are better reasons to have it the way it is than that way. The biggest reason to not be const by default is backwards comparability. To change the default mutability of variables would break nearly every non-const declaration (the only ones it wouldn;t break are those that could have been const). |
| Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Aug 25 01:38AM +0100 On Thu, 23 Aug 2018 05:48:38 -0000 (UTC) > Even beyond that, in the era of C++11 and newer, the constness of > a member function should indicate that it's thread-safe to call it > without a locking mechanism. It absolutely doesn't mean that. Locking of object (instance) data is required in a const member function if it accesses those data at a time when a non-const member function might concurrently mutate the data in another thread. You may have got this idea from a talk given by Herb Sutter in which he asserted that "const means thread safe". It doesn't. A const member function can also mutate static data. |
| Juha Nieminen <nospam@thanks.invalid>: Aug 25 08:01AM > object. That does not mean it will not be changed from another thread. > So the promise is not that it does not change because the function has no > control of this. What being "thread-safe" means in this case is that two threads can safely call that function without problems. It's not a guarantee that if one thread calls *another* function of the class then *this* function will behave properly. This is in contrast with non-const member functions: Two threads cannot safely call said function without a locking mechanism (unless the description of the function guarantees that it's thread-safe, of course). In general, from C++11 forward you should design your const member functions in this manner. 'const' ought to be a promise that it can be safely called from multiple threads. |
| Juha Nieminen <nospam@thanks.invalid>: Aug 25 08:06AM > required in a const member function if it accesses those data at a time > when a non-const member function might concurrently mutate the data in > another thread. Thread-safety in this case means that two threads can call *that* function in question without problems. It does *not* refer to on thread calling const function A, and another thread calling a non-const function B at the same time. > You may have got this idea from a talk given by Herb Sutter in which he > asserted that "const means thread safe". It doesn't. I don't usually resort to argument for authority, but in this case I'm making an exception. > A const member function can also mutate static data. And it really shouldn't. That's the point. (Why does nodoby understand the difference between the words "should" and "does"? Read my original text again, which you quoted above.) |
| Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Aug 25 04:29PM +0100 On Sat, 25 Aug 2018 08:06:47 -0000 (UTC) > in question without problems. It does *not* refer to on thread calling > const function A, and another thread calling a non-const function B at > the same time. What you said was: "Even beyond that, in the era of C++11 and newer, the constness of a member function should indicate that it's thread-safe to call it without a locking mechanism." That is just plain wrong. The only way of finding that out is to inspect the code and its documentation. It is not sufficient to examine the signatures of the const functions to check that they are indeed marked 'const'. You have to see if any of the data accessed by the const function(s) can be concurrently mutated by other threads. > And it really shouldn't. That's the point. > (Why does nodoby understand the difference between the words "should" > and "does"? Read my original text again, which you quoted above.) I wasn't discussing whether a const member function _should_ be able to mutate global and static data. My point was that according to the C++ standard it _can_, which is another reason why calling const member functions is NOT automatically thread safe by virtue of the fact that they are marked const. |
| Juha Nieminen <nospam@thanks.invalid>: Aug 25 05:47PM > examine the signatures of the const functions to check that they are > indeed marked 'const'. You have to see if any of the data accessed by > the const function(s) can be concurrently mutated by other threads. Do you have trouble understanding what the word "should" means? The constness of a member function SHOULD indicate that it's thread-safe. SHOULD. Not "does". As in, you ought to implement the method so that it's thread-safe to call it, as a good programming practice. What other word can I use to make it clearer? > I wasn't discussing whether a const member function _should_ be able to > mutate global and static data. But I was. |
| Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Aug 25 07:14PM +0100 On Sat, 25 Aug 2018 17:47:46 -0000 (UTC) > SHOULD. Not "does". As in, you ought to implement the method so that > it's thread-safe to call it, as a good programming practice. > What other word can I use to make it clearer? So what you are really proposing is a coding standard. You propose that any member function which is labeled 'const' "should", in order to comply with your standard, also be thread safe, so that if the object concerned can be mutated concurrently in another thread, it should also be protected by an internal mutex or similar internal synchronisation. The standard library doesn't guarantee that, so I think you are onto a loser. It would also be unnecessarily inefficient. All that the C++ standard guarantees is that a const member function can safely be called concurrently with another thread calling that or another const member function on the same object, provided that no non-const member function is called concurrently on the object. Otherwise "a locking mechanism" (your words) is required when invoking the const member functions (and any non-const member function). In order to describe a function as "thread safe" you must be able to call it safely in one thread irrespective of what another thread is doing. What "thread safe" means is that you do not have to provide external synchronisation. The fact is that no code that I know of complies with your coding standard for 'const'. So it may be true that in your opinion "the constness of a member function should indicate that it's thread-safe to call it without a locking mechanism", in the real world the standard library doesn't do so, so it doesn't. |
| "Öö Tiib" <ootiib@hot.ee>: Aug 25 12:12AM -0700 On Friday, 24 August 2018 11:04:09 UTC+3, Alf P. Steinbach wrote: > cout << boolalpha; > cout << noexcept( true? 0 : throw 0 ) << endl; > } That does not work because compiler does not evaluate it as constexpr. Also constexpr casts do not exist so got to put it into constexpr function at least. That seems to work on gcc: #include <iostream> bool constexpr is42(int i) {return i == 42? true : throw 0;} int main() { int a = 42; int const b = 42; int constexpr c = 3; std::cout << std::boolalpha; std::cout << "is42(a) " << noexcept(is42(a)) << "\n"; std::cout << "is42(b) " << noexcept(is42(b)) << "\n"; std::cout << "is42(c) " << noexcept(is42(c)) << "\n"; } |
| You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page. To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
No comments:
Post a Comment