Friday, December 1, 2017

Digest for comp.lang.c++@googlegroups.com - 14 updates in 4 topics

Juha Nieminen <nospam@thanks.invalid>: Dec 01 06:47AM

> }
> when built with GCC, the push_back line works fine, but the emplace_back
> one doesn't. WTH?
 
They are not equivalent.
 
foo.push_back({something}) is equivalent to to foo.push_back(s{something})
(because push_back() takes a parameter of type s by reference). You are
effectively constructing an object of type s first, and then passing that
object to push_back().
 
However, foo.emplace_back(something) will take the parameter as-is, and
try to forward it to the constructor of an object of type s. In this case
{3,4} is of type std::initializer_list, and s has no constructor that
takes such a thing.
 
This ought to work (for a similar reason why the push_back() version does):
foo.emplace_back(s{3,4});
Vir Campestris <vir.campestris@invalid.invalid>: Dec 01 09:53PM

On 01/12/2017 06:47, Juha Nieminen wrote:
> takes such a thing.
 
> This ought to work (for a similar reason why the push_back() version does):
> foo.emplace_back(s{3,4});
 
Right. That makes perfect sense.
 
Or does it?
 
In the case foo.push_back(s{something}) what (default) constructor of s
is being called? Isn't {3,4} an initialiser list there too?
 
Andy
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 01 10:07PM

On Fri, 1 Dec 2017 21:53:25 +0000
 
> Or does it?
 
> In the case foo.push_back(s{something}) what (default) constructor of
> s is being called? Isn't {3,4} an initialiser list there too?
 
The initialisation of the temporary in 'foo.push_back(s{3,4})' and
'foo.emplace_back(s{3,4})' have effect as a call to a constructor
taking two arguments if 's' has no initialiser list constructor. Why
does this not occur with foo.emplace_back({3,4})? Probably because
emplace_back is function templated on its arguments and this is an
artefact of the template deduction rules: once deduced as an
initialiser list, always deduced as an initialiser list.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 01 10:20PM

On Fri, 1 Dec 2017 22:07:26 +0000
 
> The initialisation of the temporary in 'foo.push_back(s{3,4})' and
> 'foo.emplace_back(s{3,4})' have effect as a call to a constructor
> taking two arguments if 's' has no initialiser list constructor.
 
Corrigendum: Or in this case, as an aggregate initialisation, as there
is no explicit constructor.
 
Vir Campestris <vir.campestris@invalid.invalid>: Dec 01 11:01PM

On 01/12/2017 22:20, Chris Vine wrote:
> Corrigendum: Or in this case, as an aggregate initialisation, as there
> is no explicit constructor.
 
Ah! That'll be it.
 
Thanks to you and Juha.
 
Andy
bitrex <bitrex@de.lete.earthlink.net>: Nov 30 08:37PM -0500

On 11/30/2017 09:21 AM, Rick C. Hodgin wrote:
> protected under the law. They should have that protection. The use of
> that pre-existing tool should be at their disposal when the entity who
> originally held rights to it walks away.
 
The problem is determining what "entity" we're talking about and what
constitutes "walking away."
 
There are a lot of old PC games that were left behind as consumer's
interest waned in favor of newer material, but they were never released
into the public domain and someone or other held onto the rights to
them. Eventually technology caught up and it got to the point that those
games could be run in a browser window or on a virtual machine with
little overhead compared to a modern machine's processing power, and
some consumer's interest turned back toward's "vintage" gaming.
 
A few weekends ago my GF and I played through an old King Arthur game
called Conquests of Camelot published back in 1990 or so; I'd played it
when I was a kid and it was still an enjoyable experience all these
years later. I could've gotten it off a torrent site or something but it
was also available on gog.com packaged up in a DOSBox wrapper and ready
to go on a modern machine.
 
<https://en.wikipedia.org/wiki/Conquests_of_Camelot:_The_Search_for_the_Grail>
 
AFAIK the original creators are still living and retained the rights to
it and will receive a fair cut of the purchase price which in 2017 was
$5.99, which seems perfectly reasonable.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 01 09:58PM

On Thu, 30 Nov 2017 20:37:40 -0500
bitrex <bitrex@de.lete.earthlink.net> wrote:
[snip]
 
This is off topic in a C++ newsgroup and you are responding to a known
spammer. It would be great if you could desist.
Juha Nieminen <nospam@thanks.invalid>: Dec 01 06:40AM

> That does not cover the case of a user-defined namespace named std
> within a user-defined namespace.
 
Maybe this is an omission in the standard. I think that it should be
specific about this (ie. either forbidding it, or specifically
allowing it).
 
Anybody has any contacts in the standardization committee, so they could
send a comment about this?
"James R. Kuyper" <jameskuyper@verizon.net>: Dec 01 10:36AM -0500

On 12/01/2017 01:40 AM, Juha Nieminen wrote:
 
> Maybe this is an omission in the standard. I think that it should be
> specific about this (ie. either forbidding it, or specifically
> allowing it).
 
If the intent were to allow it, it would be contrary to the way the
standard is normally written to specifically say so. There's a general
rule that allows creation of user-named name spaces, and as far as I can
see, there's no exception to that rule for one that is named "std". The
namespace ::std is already defined by the standard, and there are
explicit rules governing what a program can do in that namespace, but I
believe it says nothing about, for example, ::kuyper::std. if I'm right
about that, that's sufficient to allow such a namespace.
woodbrian77@gmail.com: Dec 01 09:50AM -0800

On Friday, December 1, 2017 at 12:40:54 AM UTC-6, Juha Nieminen wrote:
> allowing it).
 
> Anybody has any contacts in the standardization committee, so they could
> send a comment about this?
 
I haven't found it difficult to find email addresses for
people on the committee. For the most part, they have
replied to my emails.
 
With a lot of things slipping through the cracks for C++
2017, I think the committee is under pressure to not blow it
again for C++ 2020. So I'm not sure how interested they
would be in this matter.
 
 
Brian
Ebenezer Enterprises - Enjoying programming again.
http://webEbenezer.net
"Öö Tiib" <ootiib@hot.ee>: Nov 30 03:27PM -0800

On Friday, 1 December 2017 00:59:54 UTC+2, Christian Gollwitzer wrote:
> > Not a homework problem, too dumb for school.
> > https://forum.level1techs.com/t/c-openmp/121868
 
> You manipulate "x" (is this a global std::vector?) inside of
 
To me x seems to be protected std::vector<float> member of Stats
that is virtual base class of Sample whose instance the sample likely
is.
The '#pragma omp parallel for private(sample)' does separate copy
of that sample for each iteration. It can be that those copies
somehow fragment memory and cause the problems.
 
> protect with locks (lock_guard<>), or duplicate the vector. And even
> better, remove the global. It is not sure where it is coming from, since
> you don't show complete compilable code.
 
Yes. My comments above can be wrong because we haven't seen any actual
program code, just what may be fragments of it and reports that the
program "dies".
Riccardo Zanella <riiccardo.zanella_RE_MOVE@gmail.com>: Dec 01 01:13AM +0100

Il 30/11/17 03:12, Bob ha scritto:
> Not a homework problem, too dumb for school.
> https://forum.level1techs.com/t/c-openmp/121868
 
I got no problem up to 30k, too tired to try more :)
Then I changed to c++11 and random generators, please check whether the
generation fits your needs.
 
Compile with:
g++-6 -std=c++11 -fopenmp -O2 -march=native main.cpp stats.cpp -lgomp
 
Remember to set something, for Bash you can use:
export OMP_NUM_THREADS=2
export OMP_SCHEDULE=static,1
 
Riccardo
 
===== main.cpp =============
#include <vector>
#include <stdexcept>
#include <sstream>
#include <iostream>
#include <cstdlib>
#include <omp.h>
 
#include "stats.hpp"
 
int main( int argc, char *argv[]) {
try {
int n = 50;
if (argc == 2)
if( (std::istringstream(argv[1]) >> n).fail() || (n < 1) )
throw std::runtime_error("bad input");
 
std::cerr << "Up to " << n << std::endl;
std::vector< float > x (n);
Sample sample;
std::vector< std::vector<float> > table(n-1);
for ( int ii = 0; ii < n-1; ++ii )
table[ii] = std::vector< float >(8);
 
double start = omp_get_wtime();
 
# pragma omp parallel for private(sample) schedule(runtime)
for( int ii = 2; ii < n+1; ++ii ){
if ( (ii % 1000 == 0) )
std::cerr << ".";
sample.randomSample(x, ii);
table[ii-2][0] = sample.computeMean();
table[ii-2][1] = sample.computeMedian();
table[ii-2][2] = sample.computeVar();
table[ii-2][3] = sample.computeStd();
table[ii-2][4] = sample.computeMeanDev();
table[ii-2][5] = sample.computeMedianDev();
table[ii-2][6] = sample.computeSkewness();
table[ii-2][7] = sample.computeMedianSkew();
}
double end = omp_get_wtime();
std::cout << std::endl
<< "Time: " << end -start << "[s]" << std::endl;
}
catch ( std::exception &e ){
std::cerr << e.what() << std::endl;
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
 
 
===== stats.cpp (excerpt) =============
#include <random>
 
void Sample::randomSample(const std::vector<float>& pop, int m)
{
if (m <= 0) {
n = 0;
return;
}
n = m;
int pop_size = pop.size();
// use an index vector - preserve passed vector
std::vector<int> idx(pop_size); // <--------------------------
for (int i = 0; i < pop_size; i++) idx.push_back(i);
// perform pop_size random swaps
std::default_random_engine eng{ static_cast< long unsigned int >
(time(0))};
std::uniform_int_distribution<int> gen( 0, pop_size-1 );
for (int i = 0; i < pop_size; i++) {
// int rndidx = (int)(pop_size*((float)rand()/(float)IMAX));
int rndidx = gen(eng);
int tmp = idx[i];
idx[i] = idx[rndidx];
idx[rndidx] = tmp;
}
// x.clear(); // clear in case something is there
x.resize(n); // <------------------
for (int i = 0; i < n; i++) // x.push_back(pop[idx[i]]);
x[i] = pop[idx[i]]; // <------------------
}
Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid>: Dec 01 12:45PM +0100

> The '#pragma omp parallel for private(sample)' does separate copy
> of that sample for each iteration. It can be that those copies
> somehow fragment memory and cause the problems.
 
The OpenMP spec describes private (in the case of C++), in Section
2.15.3.3, as:
 
| The new list item is initialized, or has an undefined initial value, as
| if it had been locally declared without an initializer.
 
"List item" here is an item in the private clause. The "new" list item
is the one allocated for each thread.
 
And later:
 
| A variable of class type (or array thereof) that appears in a private
| clause requires an accessible, unambiguous default constructor for the
| class type.
 
 
> Yes. My comments above can be wrong because we haven't seen any actual
> program code, just what may be fragments of it and reports that the
> program "dies".
 
Right, the code does not show the relevant parts. Probably
race-conditions on data referenced inside sample (and copies thereof).
 
-- Alain.
"Necron_99" <user@foobar.com.invalid>: Dec 01 05:22PM

Thank you, this was the branch of the thread that proved to be most relevant.
 
Alain Ketterlin <alain@universite-de-strasbourg.fr.invalid> wrote in
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: