comp.lang.c++@googlegroups.com | Google Groups | ![]() |
Unsure why you received this message? You previously subscribed to digests from this group, but we haven't been sending them for a while. We fixed that, but if you don't want to get these messages, send an email to comp.lang.c+++unsubscribe@googlegroups.com. |
- ++++i; - 4 Updates
- "A quick poll about order of evaluation…" - 5 Updates
- Which STL container to use? - 4 Updates
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Dec 02 06:14PM On 02/12/2014 17:49, Mr Flibble wrote: > ++++i; > Here i is modified twice in the same expression so I think it is UB but > I'm not 100% sure. Some are saying that it is possibly UB in C++03 but fine in C++11. Mystified. /Flibble |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 02 07:43PM On Tue, 02 Dec 2014 18:14:21 +0000 > Some are saying that it is possibly UB in C++03 but fine in C++11. > Mystified. > /Flibble As am I. But whatever, just use the comma operator (++i, ++i), which is always right. Chris |
scott@slp53.sl.home (Scott Lurndal): Dec 02 09:15PM >> /Flibble >As am I. But whatever, just use the comma operator (++i, ++i), which is >always right. I guess I don't see why either alternative is superior to i += 2 |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Dec 02 11:27PM On 02/12/2014 21:15, Scott Lurndal wrote: >> As am I. But whatever, just use the comma operator (++i, ++i), which is >> always right. > I guess I don't see why either alternative is superior to i += 2 If 'i' is a bi-directional (not random access) iterator the += 2 won't work. /Flibble |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 02 07:04PM On Tue, 02 Dec 2014 08:49:30 -0500 > problems you might wish for help, and since "undefined behavior" can > include catching the situation and calling you a dummy, sometimes you > can turn on debug modes/tools to help you. I agree with that for the most part, but what annoys me most about C++ with regard to this, and I think offers little or no optimization opportunities in return, is not unordered evaluation as such, but the permit to partially evaluate. Take a function: void func(std::unique_ptr<T1> a, std::unique_ptr<T2> b); In the C++11 world (which does not have make_unique) the following code represents a possible memory leak in the presence of an exception: func(std::unique_ptr<T1>{new T1{val1}}, std::unique_ptr<T2>{new T2{val2}}); The problem with this is not that the order of evaluation of the arguments is unspecified, but because the compiler is entitled to partially evaluate by first evaluating the 'new T1{val1}' expression and then evaluating the new 'T2{val2}' expression (or vice versa) before constructing either unique_ptr object. This is OK with C but vastly annoying with a language with exceptions such as C++. For exception safety you have to do explicit sequencing yourself by hand, viz: auto t1 = std::unique_ptr<T1>{new T1{val1}; auto t2 = std::unique_ptr<T2>{new T2{val2}; func(std::move(t1), std::move(t2)); which is a pain in the butt. I would really like to see that dealt with. The std::unique_ptr issue is mostly solved by C++14's make_unique, but there are many other cases where you might want to use handles where similar issues arise. Chris |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 02 07:21PM On Tue, 02 Dec 2014 10:43:45 -0800 > shall be met for each allowable ordering of the subexpressions of a > full expression; *otherwise the behavior is undefined*. > (emphases mine) C++11, §1.9/15: "Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. ... . If a side effect on a scalar object is unsequenced relative to either another side effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined. [ Example: ... i = v[i++]; // the behavior is undefined " C++14 is similar, although it imports an additional forward reference to concurrency issues (§1.9/15 is concerned with the sequencing in a single thread only). Chris |
JiiPee <no@notvalid.com>: Dec 02 07:51PM On 02/12/2014 18:46, red floyd wrote: > It's explicitly UB. See the quote from the (2003) standard that I > posted upthread. ok I got it. Its clear then... |
Marcel Mueller <news.5.maazl@spamgourmet.org>: Dec 02 10:13PM +0100 On 01.12.14 21.54, Lynn McGuire wrote: > unspecified behavior." > "Rather, my question is what you would like the result to be. Please let > me know." Let's write it explicitly (I include the this pointers): operator=(operator[](&v, i++), i++); Each operator function call is a sequence point, but the two arguments of operator= have no defined ordering. So the evaluation sequence of the access to i is still undefined. => definitely undefined behavior. Marcel |
Paavo Helde <myfirstname@osa.pri.ee>: Dec 02 03:46PM -0600 > unspecified behavior." > "Rather, my question is what you would like the result to be. Please > let me know." I would like this to be a diagnosed error. A coworker of mine wrote some similar code, but later he himself was not able to say which output he expected. Neither can I with the above example, "10" seems as valid answer as "02". Cheers Paavo |
Christopher Pisz <nospam@notanaddress.com>: Dec 01 05:57PM -0600 On 12/1/2014 2:13 PM, Ian Collins wrote: >> Do you agree with the flowchart at bottom of page? > While it leads to a correct solution for simple applications, it might > not lead too an optimal solution. Too few paths lead to vector. Aye. There was some discussion a while back about all things implemented with list should be implemented using vector for the contiguous memory to take advantage if cache hits. Still need to test this out myself more extensively. |
legalize+jeeves@mail.xmission.com (Richard): Dec 02 12:05AM [Please do not mail me a copy of your followup] Robert Hutchings <rm.hutchings@gmail.com> spake the secret code >http://homepages.e3.net.nz/~djm/cppcontainers.html >Do you agree with the flowchart at bottom of page? Seems pretty complicated and obscures the most important advice: Use vector as your first choice for container. -- "The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline> The Computer Graphics Museum <http://computergraphicsmuseum.org> The Terminals Wiki <http://terminals.classiccmp.org> Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com> |
"Öö Tiib" <ootiib@hot.ee>: Dec 01 04:14PM -0800 On Monday, 1 December 2014 22:01:49 UTC+2, Robert Hutchings wrote: > http://homepages.e3.net.nz/~djm/cppcontainers.html > Do you agree with the flowchart at bottom of page? Generally it is OK chart. Few remarks. * When people are first unsure about the performance characteristics yet then they should take 'std::vector' and if later there's time then revisit that choice. Being unsure is quite standard state of software developer's mind and lack of time is also quite usual situation later so most containers in C++ program should be 'std::vector'. ;) * The logic that leads to some rather common choices like 'std_pair', 'std::tuple', 'std::array' and 'std::unordered_*' is entirely missing from the chart. * Some logic should lead to 'std::bitset' (it performs usually way better than 'std::array<bool,?>' or 'std::set<some_enum_type>' ). * Any such guide should at least mention some very well-performing containers of Boost (that often outperform the 'std') like 'boost::flat_*' and 'boost::intrusive::*'. |
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 02 10:15AM On Mon, 01 Dec 2014 14:01:12 -0600 > http://homepages.e3.net.nz/~djm/cppcontainers.html > Do you agree with the flowchart at bottom of page? No. If a container is never accessed concurrently in more than one thread, and its contained elements are built-in types, then use std::vector unless in extraordinary circumstances. If the contained elements have non-throwing move-constructor/move-assignment-operator then also strongly consider std::vector unless the internal implementation of the element is mainly constructed on the heap, in which case you will be suffering cache misses anyway and if you are frequently inserting/removing elements other than at the end of the vector you might get better performance with another container. But profile first. Don't use ordered associative containers unless profiling shows they are better (they almost always aren't even when you think they should be). There is a reason why smalltalk is slow. Treat the unordered associative containers with suspicion, but they do have good use cases. Use std::list with splicing/unsplicing to minimize contention if a queue-type or stack-type container may be accessed/modified concurrently by more than one thread, to minimize contention on locks, particularly if the element has a non-throwing move constructor. The gain from reduced contention will generally more than offset additional cache misses if contention would otherwise cause scalability issues. Chris |
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