- "Bjarne Stroustrup announces C++ Core Guidelines" - 6 Updates
- using #define vs const int , in error codes - 1 Update
- Newfangled constructs - 5 Updates
- "Breaking all the Eggs in C++" by Scott Meyers - 2 Updates
- Help improving this little function, if necessary. - 2 Updates
- scandir help - 1 Update
- Help improving this little function, if necessary. - 7 Updates
- io.h, reading contents of a directory, ubuntu 14.04 - 1 Update
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Nov 18 11:42PM On 18 Nov 2015 21:08:04 GMT > > object foo points to". > Sorry; I can't see the difference, unless you mean foo->bar->baz = 1, > which I agree would be fair to describe. I do not know what 'foo->bar->baz = 1' refers to, as I have not seen your Foo class definition (have I missed a post somewhere? - if so my apologies). You said '"const Foo* foo" just means "I can't use 'foo' to modify anything"'. I took from this (and from the posting to which you were replying) that this was intended as a general statement about the qualities of 'const', rather than about a particular Foo class definition which I have not seen. Saying that foo cannot modify anything is a statement that it is pure. Taken on that basis, what you said was wrong. This is valid code, but it modifies 'a', 'b', and the state of the output stream: #include <iostream> int a = 0; struct Foo { static int b; int do_it1() const {++a; std::cout << a << '\n'; return a;} int do_it2() const {++b; std::cout << b << '\n'; return b;} }; int Foo::b = 0; int main () { const Foo* foo = new Foo; foo->do_it1(); foo->do_it2(); delete foo; } > > irrespective of whether there is any mutable object data around.) > > "const" does not mean "no side effects". > I don't know what "pure" means either, to be honest, It refers to the absence of side effects. It requires amongst other things that a function only depend on its arguments (in particular, not on mutable state), and that the same input value(s) should always produce the same return value. No function returning void could be pure, because otherwise it would not do anything. It enables many compiler optimizations, including lazy evaluation, common subexpression elimination and memoization, and (because it doesn't silently change program state) makes programs easier to reason about and facilitates safe concurrency - all pure functions are by definition thread safe). D has a 'pure' keyword, for example. I think all constexpr functions must in fact be pure (I must look that up some time), but there are many pure functions which are not constexpr. This is not to be confused with gcc's C function 'const' attribute, which does require purity. Chris |
"Öö Tiib" <ootiib@hot.ee>: Nov 18 06:14PM -0800 On Thursday, 19 November 2015 00:27:07 UTC+2, Ian Collins wrote: > > Consequently I never use in-class function definitions (except for some > > rare cases where the body is empty and I'm lazy). > So you never use templates? AFAIK every member or friend function of class or class template (also templates of such functions and inline functions) can be defined outside of class definition. So the only question is if it is worth doing on case of templates and inline functions. |
scott@slp53.sl.home (Scott Lurndal): Nov 19 03:41PM >> Consequently I never use in-class function definitions (except for some >> rare cases where the body is empty and I'm lazy). >So you never use templates? While I write template functions, I've not yet encountered a case where it was necessary to write a template class (as opposed to _using_ one from a library). I also place private data members at the top of the class, and define inline functions after the class (which allows them to be moved to a separate header file when circular dependencies exist). Multiline functions within the class definition seriously impair readability, IMO. |
"Tobias Müller" <troplin@bluewin.ch>: Nov 19 08:13PM > I'm using them more over the past year or two. I've > found some minor advantages from going this route in > terms of executable/binary code size. I find this hard to believe. I still use inline functions in the header, just not in the class body. Those should be equivalent. > functions like less lines of code. Imo that makes > the library or program, as a whole, easier to work > with. How so. I don't care about the size of the files as long as the *relevant* part (the class definition) is concise. By stuffing everything into the class body, you make it harder to work with, not easier. > The more compact form for the software > also helps in terms of downloading/bandwidth. Usually you use compression for that. Tobi |
"Tobias Müller" <troplin@bluewin.ch>: Nov 19 08:18PM > non-template code, I prefer not to have inline protected or private > inline function. The former may be heavily used in client code, so > making them available to the optimiser for inlining makes sense. I often use inline functions and templates, sure. Just not inside the class body. It's equivalent but the same. Tobi |
"Tobias Müller" <troplin@bluewin.ch>: Nov 19 08:20PM > I often use inline functions and templates, sure. Just not inside the class > body. It's equivalent but the same. *not* the same. |
legalize+jeeves@mail.xmission.com (Richard): Nov 19 07:32PM [Please do not mail me a copy of your followup] Ben Bacarisse <ben.usenet@bsb.me.uk> spake the secret code > "During 1973-1980, the language grew a bit: the type structure gained > unsigned, long, union, and enumeration types, and structures became > nearly first-class objects (lacking only a notation for literals)."[1] Nice; thanks for the research. So why are we arguing about avoiding solutions that have been available for 35 years? -- "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> |
Juha Nieminen <nospam@thanks.invalid>: Nov 19 09:16AM > The newfangled ranged based for loops whilst dinky and useful do have an > irritating niggle: how to break out of nested loops? You put it into its own function (and use a return). There's a reason why modern programming design guidelines instruct to split code into smaller logical functions. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
seeplus <gizmomaker@bigpond.com>: Nov 19 02:47AM -0800 On Thursday, November 19, 2015 at 6:04:49 AM UTC+11, Mr Flibble wrote: > } > } > found: Does that goto version work if you are going to actually use "found"? Doesn't it end up at "found" if it does find... but also when it gets hit at the end of the main for loop .... and there is no way of knowing which event happened. By coincidence yesterday I had to write a complicated version of this using medium newfangled (! not with goto!) and there seems to be no way of escaping having a BOOL in there. |
Luca Risolia <luca.risolia@linux-projects.org>: Nov 19 05:25PM +0100 On 18/11/2015 20:04, Mr Flibble wrote: > } > } > But I am not convinced. What to do sausages? :/ lambdas? bool found = [&] { for (auto& e1 : seq1) { for (auto& e2 : seq2) { if (e2 == 42) return true; } } return false; }(); |
red floyd <no.spam@its.invalid>: Nov 19 09:59AM -0800 On 11/18/2015 11:32 AM, Mr Flibble wrote: > Not compatible with destructors AFAIK sausages. > /Flibble Alternatively: try { for (auto& e1 : seq1) { for (auto& e2) { if (e2 == 42) throw 42; } } } catch (int) { } I'd almost prefer the goto. IMHO, breaking out of nested loops is the only legitimate use of goto. |
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Nov 19 07:28PM On 19/11/2015 09:16, Juha Nieminen wrote: > You put it into its own function (and use a return). > There's a reason why modern programming design guidelines instruct to split > code into smaller logical functions. Unnecessary functional decomposition can often increase a program's complexity and in this case it is only necessary due to a shortcoming in the language's syntax sausages. /Flibble |
Juha Nieminen <nospam@thanks.invalid>: Nov 19 09:09AM >>> You should realise that C++ isn't mature yet, >>Could you provide an example of a mature programming language? > ALGOL? Bliss-32? Focal? BPL? SPL? Is "mature language" a synonym for "long ago dead fringe language"? --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
scott@slp53.sl.home (Scott Lurndal): Nov 19 03:37PM >>>Could you provide an example of a mature programming language? >> ALGOL? Bliss-32? Focal? BPL? SPL? >Is "mature language" a synonym for "long ago dead fringe language"? ALGOL is not at all dead, and is in production today at hundreds of sites. Yes, the VAX is toast, so Bliss-32 (which was really mainly used internally at DEC) is dead. Focal was widely used in its day, with ports to PDP8, PDP11, VAX and others. There is still a bit of BPL code running after 40 years. SPL (the systems programming language for the HP-3000) has been dead for a while to the best of my knowledge. |
ram@zedat.fu-berlin.de (Stefan Ram): Nov 19 12:57AM >Be sure to measure the right thing, though, i.e. be sure to ask your >compiler to optimize for speed. Usually that's an option like "-O2". But ... and then try to optimize for memory. Sometimes, it happens that the code then will fit into a cache, and the code optimized for memory will actually run faster that the code that was optimized for speed. >Here you should >* hint to the compiler to inline calls to this function, by using the >keyword "inline", Which might also actually slow down the code, when it will not fit into a cache anymore after the inlining. >The temporary vector is expensive because unlike `std::string`, a vector >cannot use the short buffer optimization, and so the above code incurs a >dynamic allocation -- really expensive in this context. In other cases, when a function does not have to be recursive or thread-safe, such a temp buffer might be allocated once with static lifetime and reused. |
ram@zedat.fu-berlin.de (Stefan Ram): Nov 19 11:15AM > }(); > // Use "found" here. >Well, OK, that wasn't so bad as I feared. Can we also use something like »inline« on such function expressions? I thought about the same solution, but within a named function that has the »inline« attribute. In this case, the function call does not take place in an inner loop, at least it is outside of the loop visible above. Still, it would be good to know that the extra function wrapper does not waste any run-time. |
Juha Nieminen <nospam@thanks.invalid>: Nov 19 09:11AM > #include <cmath> > #include <ctime> > #include <string> I think you missed a few includes there. There are still plenty in the standard (and system) library. --- news://freenews.netfront.net/ - complaints: news@netfront.net --- |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 19 01:45AM +0100 On 11/18/2015 10:30 PM, Noob wrote: > I'm new to C++, coming from Fortran. I'd like some help writing the > following function in a way to improve speed, if it turns out to be to > badly written. For numerical operations using Fortran used to be a good way to speed up things. Most numerical libraries started out as Fortran libraries. I don't know how that is today, but I think going from Fortran to C++ is not likely to /improve/ the speed significantly. Anyway, the first and also second rule of optimization is to MEASURE. Be sure to measure the right thing, though, i.e. be sure to ask your compiler to optimize for speed. Usually that's an option like "-O2". But consult your compiler's or IDE's documentation or GUI. Also define "NDEBUG" to remove assertion checking. It's generally a good idea to leave assertion checking on, but not in time-critical code. > int eval_lgk(const std::vector<int> coords, > const std::vector<double>factsgk) Here you should * hint to the compiler to inline calls to this function, by using the keyword "inline", * pass the arguments by reference to const, not by value. Passing by value the arguments are (at least logically) copied, and such copying involves expensive dynamic allocations unless it's optimized away by the implementation. > { > unsigned int nvars = coords.size(); For clarity it's best to declare "nvars" as "const". Sprinkle "const" liberally throughout your code, wherever possible. That way you can see at a glance, up front, that that value will not be changing, and this helps to understand the code faster, and avoid silly mistakes. Also, at this point add assert( nvars >= 2 ); Include the "<assert.h>" header for that. If nvars is 0 then the declaration below will declare a really huge "temp" vector, and if nvars <= 1 then the loop will likewise loop a really large number of times. > { > temp[i] = factsgk[i] * ( coords[i] - 1.0 ); > } Either this loop is incorrect, or else the declaration of "temp" is incorrect (apart from the item type which you have explained in a follow-up should be "int"). "temp" has nvars-1 items, but only nvars-2 items are assigned to. By the way, although the compiler is almost sure to optimize this, introducing a name for "coords.size()" and then calling "coord.size()" again is a lost nano-optimization opportunity. > return coords[nvars-1] + > std::accumulate(temp.begin(),temp.end(),0.0); Are you sure that the "factsgk[nvars-1]" value doesn't exist or should be ignored? Additionally, instead of using a temporary vector just accumulate the sum in the loop. The temporary vector is expensive because unlike `std::string`, a vector cannot use the short buffer optimization, and so the above code incurs a dynamic allocation -- really expensive in this context. > In real cases, factsgk and coords will both have size of about 3 to > 5, say, but this function will be called many, many times inside loops > and I'd like to write it in a way I can get good speed. A general speedup might possibly be achieved by deferring this work until you have zillion or two postponed calls. Then you could do them all in parallel in the graphics card. A little dirty yes but still. But first, make the code clearly correct. The "assert" macro is a good tool to employ for that. Cheers & hth., - Alf |
Ian Collins <ian-news@hotmail.com>: Nov 19 02:02PM +1300 Stefan Ram wrote: >> keyword "inline", > Which might also actually slow down the code, when it > will not fit into a cache anymore after the inlining. Which is why the inline keyword is pointless in this context. -- Ian Collins |
Noob <dontspam@me.com>: Nov 18 11:18PM -0200 On 18/11/2015 22:45, Alf P. Steinbach wrote: > Cheers & hth., > - Alf Thank you very much for all your remarks! I apologize for posting a code with logic errors prior to C++ mistakes. I know it is no excuse but the whole deal about array indexing starting at 1 in Fortran and 0 in C++ lead me to some mistakes when I wrote the code for my post. The temp array was there for no logic reason other than the fact that it remained from another version of the snippet I typed before posting the final version. What I have at the moment now is this int eval_lgk(std::vector<int>& coords, std::vector<int>& factsgk) { assert( factsgk.size() == coords.size() && coords.size() >= 1 ); int partial = coords.back(); for (size_t i = 0; i < coords.size()-1; i++) { partial+= factsgk[i] * ( coords[i] - 1 ); } return partial; } For the moment, I can say that working with arrays is easier in Fortran, but then there are a lot of other things C++ is allowing me to do much cleaner and quicker. I suppose I can start afresh from this. Having this construct: An element-wise vector multiplication, followed by a "reduction", is this a good way to code it or can I use some more compact syntax which will also let the compiler do possibly a better job? Thanks! |
Noob <dontspam@me.com>: Nov 18 11:19PM -0200 On 18/11/2015 20:36, Stefan Ram wrote: >> I'd like to write it in a way I can get good speed. > You already have good speed. > If you really want to optimize: Start by using a profiler. Will do. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 19 02:19AM +0100 On 11/19/2015 2:02 AM, Ian Collins wrote: >> Which might also actually slow down the code, when it >> will not fit into a cache anymore after the inlining. > Which is why the inline keyword is pointless in this context. Not pointless, but as mentioned, it's important to MEASURE. This is a very short function that's called a zillion times, so inlining is likely to improve things. This is precisely the kind of function that machine code inlining is /for/. Still nothing's guaranteed: only measuring can tell for sure, or reduce doubt about it. In addition to being aware of the rôle of caching, one should be aware that some compilers (like g++) take the "inline" hint very seriously, while others may ignore it, so measuring should ideally be done for all relevant compilers and target systems, etc. Cheers, - Alf |
Ian Collins <ian-news@hotmail.com>: Nov 19 03:54PM +1300 Alf P. Steinbach wrote: >>> will not fit into a cache anymore after the inlining. >> Which is why the inline keyword is pointless in this context. > Not pointless, but as mentioned, it's important to MEASURE. It is pointless because the compiler generally knows better than the programmer which functions to inline. It will be able to include platform specifics in its choices. > is likely to improve things. This is precisely the kind of function that > machine code inlining is /for/. Still nothing's guaranteed: only > measuring can tell for sure, or reduce doubt about it. Which will result in in it being inlined whether the hint is there or not. > that some compilers (like g++) take the "inline" hint very seriously, > while others may ignore it, so measuring should ideally be done for all > relevant compilers and target systems, etc. All the more reason to avoid the hint - let the compiler choose. Totally agree with measuring :) -- Ian Collins |
Paavo Helde <myfirstname@osa.pri.ee>: Nov 19 12:37AM -0600 > possible. I understand somewhere something will perform this loop, but > I'm looking for something that will do it efficiently without me > coding it. You need to understand there is nothing special with STL algorithms, they are mostly template code places in the header file so they get compiled with exactly the same compiler and with exactly the same optimizer options than your code. So your loop is most probably as good as theirs. Just take care to use optimized builds in production and ensure that in these builds the NDEBUG macro is defined (this switches the assert() line off - but this probably does not matter anyway). hth Paavo |
Nobody <nobody@nowhere.invalid>: Nov 19 12:28AM On Mon, 16 Nov 2015 14:44:03 +0000, Scott Lurndal wrote: >>How do I read the contents of a directory in Ubuntu 14.04? > man readdir man 3 readdir Otherwise you might get the section 2 page. Which, to be fair, starts off with: DESCRIPTION This is not the function you are interested in. Look at readdir(3) for the POSIX conforming C library interface. |
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