Tuesday, December 2, 2014

Digest for comp.lang.c++@googlegroups.com - 13 updates in 3 topics

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.
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: