- Push_back works, but emplace_back doesn't, when constructing with initialiser list - 5 Updates
- Abandonware should fall back into the public domain - 2 Updates
- copying an aggregate (array) - 3 Updates
- C++ & OpenMP - 4 Updates
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:
Post a Comment