| ||||
| Comment on C++ and Beyond: My material for December, and early-bird registration (through June 9) by Róbert Dávid
@Brian M: C++11 is quite here, out of the four I just mentioned, only one has major black spots. (Herb, please start whipping around the appropriate office! :) ) Read More »Comment on C++ and Beyond: My material for December, and early-bird registration (through June 9) by Róbert Dávid
“We know C++14 is real and that at least two of the major commercial compilers will be implementing all of C++14 by next year.” Define “major commercial” :) There are 4 major C++ compilers: CLang, GCC, Intel Composer XE and MSVC. If I cross out the open source ones… Read More »Comment on Lost two comments by Herb Sutter
I believe duplicate/broken RSS/mail entries were also a result of the duplicate posts that were removed, and the ones with dangling links were the ones that pointed to the duplicates. Read More »Comment on GotW #6b: Const-Correctness, Part 2 by Chris
polygon() : area{-1} {} I would rather initialise area with 0 or, even better, completely remove the area member from the class since its usefulness is discussable. Constructors may be left to be synthesised by the compiler (and they probably will be synthesised due to non-trivial constructors of the points member). This will save sizeof(double) of memory per object as well. void add_point( const point pt ) { area = -1; points.push_back(pt); } Function argument is passed by copy anyway, moreover it may be copied to the vector once again. I think that constness of pt will not affect the push_back behaviour. I would suggest to pass const point& pt or use pt’s move constructor to “move” the pt’s memory to the vector (please correct me if it is not really possible). point get_point( const int i ) { return points[i]; } The value of the i may be out of bounds, this should be checked first. Const on fundamental type does nothing I suppose, it may be removed freely. Getter in general should be non-modifying, so with const modifier on a member function. Having getter in const context the points member needs to be mutable and guarded with a mutex. I wonder what is really returned from this member function, is this a “moved” item from the points vector (destructive read?) or a real copy of the points[i] item. I would try to return a const& rather than an object, but it may be pre-C++11 way of doing things… int get_num_points() { return points.size(); } I would suggest to change return type to size_t, make above getter const modified and protect the points vector with a mutex (c.f. my comment on get_point and mutable). double get_area() { I wonder how caching of a value calculated at some time is valid when multiple threads operates on the same object. I think it is not a good idea to do caching. It may break function “re-entrancy” since now such function does not depend on the actual state of the points vector solely. By the way, public member function calls private member function – this recalls me the rule to make virtuals private and call them through non-virtual public interface, unfortunately calc_area is not a virtual function. void calc_area() { This member function has read-only access to the points vector, so it should be const modified and the points member access should be protected with a mutex. Anyway, I would use std::accumulate (or custom functor) with const iterators and return the calculated value to the caller. polygon operator+( polygon& lhs, polygon& rhs ) { auto ret = lhs; I suppose we don’t want to modify lhs, so let’s make it const&. It may be quite good to add a check that will prevent from adding to itself. I would define operator+= as well. I wonder what is really stored under the auto type for ret. Is this simply a polygon type (without &)? const_cast<polygon&>(poly).add_point( {0,0} ); This code will not pass a code review round :-) void g( polygon& const poly ) { poly.add_point( {1,1} ); } I think that &const is redundant here since reference by definition is const “pointer” already. The g() looks like a better way to write h(). Read More »Comment on GotW #6b: Const-Correctness, Part 2 by Amali
As mentioned in GotW#4 Class Mechanics solution, operator + can be changed to: // add const& to rhs, remove const& from lhs polygon operator+( polygon lhs, const polygon& rhs ) { auto last = rhs.get_num_points(); for( auto i = 0; i < last; ++i ) // concatenate lhs.add_point( rhs.get_point(i) ); return lhs; } to avoid unnecessary copy auto ret = lhs;, if you’re going to do the copy anyway. Read More »Comment on GotW #4 Solution: Class Mechanics by Zenju
@Luca Risolia: operator + has left-to-right associativity, so the first parameter will have to deal with temporaries, not the second. Read More »Comment on GotW #4 Solution: Class Mechanics by Zenju
> Guideline: Prefer passing a read-only parameter by value if you're going to make a copy of the parameter anyway, because it enables move from rvalue arguments. While talking about optimizations, it should be mentioned that passing one parameter by value in order to “unify” l/r-value parameters is not the most efficient solution: T operator+(T&& a, const T& b ) So for maximum efficiency it is best to have these two overloads instead: This might seem nit-picky, but in general move-construction is not free! For example I know a string class which always has an associated control structure(alloc-count, size, ect.). Due to implementation details, the destructor cannot simply call “operator delete”, but requires a valid control structure. Comment on GotW #5 Solution: Overriding Virtual Functions by GeoffW
@Ricardo Costa: thanks for the link. It’s actually quite apt for me. I do already have a decimal type created (using the decNumber C library) with the intention it could be cut over to built-in types eventually – so I do now see the possible applicability of “final” for library code. Read More »Comment on GotW #4 Solution: Class Mechanics by Luca Risolia
@Zenju complex a; auto r = operator+(a, complex{}); a is a lvalue while the second argument is a temporary, which means operator+(const complex&, complex&&) will be called. You can easily have more convoluted expressions in which the same overload might be called. Associativity rules do not change the result for a complex type. Do I miss anything? Read More »Comment on C++ and Beyond: My material for December, and early-bird registration (through June 9) by Alex
I apologize for bringing the subject up, but somebody has to point to the elephant in the room: MSVC++11 When people complained about how little MSVC++11 brought to the table (in terms of C++11 standard compliance over MSVC++10), MS promised to address the issue by releasing free compiler updates. So far, no such updates were made available (and, no, the November CTP – from half a year ago – does not count, since it does not come with a “go live” license). So unless one of the “major commercial compilers” is such a free update to MSVC++11, you will have some explaining to do. Read More »Comment on Guru of the Week and the Exceptional C++ Series by Kelso
Generally I don’t learn post on blogs, however I wish to say that this write-up very forced me to check out and do it! Your writing taste has been surprised me. Thanks, very great article. Read More »Comment on C++ and Beyond: My material for December, and early-bird registration (through June 9) by JC_Yang
GCC probably will be the first one(4.8.1) to ship a production quality completely C++11 conform compiler, here you go: Comment on GotW #6a Solution: Const-Correctness, Part 1 by Herb Sutter GotW6: Const and Mutable | musingstudio
[…] This item covers ground Herb already presented in this video. He recommends that const member functions must be one of: […] Read More »Comment on GotW #6a Solution: Const-Correctness, Part 1 by Alexander Kramer
If const is not bitwise const anymore why not give it some new meaning, e.g. “CONSistenT” in terms of safe to be called from multiple threads. Below is an example of using Lock class (based on pthread mutex), class SafeData which uses lock for implement thread safe access to some data and class UseSafeData which shows possible usage of SafeData. At the first glance making all methods const seems ridiculous, but the benefit is that compiler will disallow calls of unsafe methods from safe methods. * all thread safe methods and members are defined using “const” This implies that synchronization primitives (locks, critical sections, …) are themselves thread safe and should provide “const” interface. For Lock class below methods lock() and unlock() are const. They also should be declared as const in other classes to restrict the usage to thread safe methods. The class SafeData provides two methods for data manipulation, one is thread safe and one is not: setDataSafe() and setData(). The class UseSafeData has two instances of SafeData and again two methods useSafe() and useUnsafe() (first is meant to be thread safe, second not). What do You think about this approach? Are there any pitfalls with new C++11? #include <pthread.h> /// Basic locking class /// const=thread safe class Lock { protected: mutable pthread_mutex_t mutex; ///< pthread mutex must be mutable public : Lock() { pthread_mutex_init(&mutex, NULL); } virtual ~Lock() { pthread_mutex_destroy(&mutex); } /// this method is thread safe and thus const void lock() const { pthread_mutex_lock(&mutex); } /// this method is thread safe and thus const void unlock() const { pthread_mutex_unlock(&mutex); } }; /// Example of class which is used in multi-threading context and has some non atomic data which requires locking. /// const = thread safe class SafeData { const Lock lock; ///< const will restrict interface of Lock to const methods mutable int dataA; ///< members which want to be protected by locks. Must be mutable. mutable int dataB; public: /// this method is thread safe (is const) void setDataSafe(int d) const { lock.lock(); printf("setDataSafe(%d) const\n",d); dataA = d; dataB = d*d; lock.unlock(); } /// this method is not thread safe void setData(int d) { printf("setData(%d)\n",d); dataA = d; dataB = d*d; } }; /// This class is also used by multiple threads and is using other thread-safe classes /// const = thread safe class UseSafeData { /// Const will restrict interface to safe methods const SafeData dataConst; /// Non-const will allow unsafe methods to be called from unsafe methods only SafeData data; public: /// thread safe method (has const) void useSafe() const { // following two lines are OK: calling safe methods from safe methods. dataConst.setDataSafe(1); data.setDataSafe(2); // following will be prevented by compiler // dataConst.setData(3); // following will be prevented by compiler because we are trying to call unsafe method from safe method. // data.setData(4); } /// not thread safe method (has no const) void useUnsafe() { dataConst.setDataSafe(5); data.setDataSafe(6); // following will be prevented by compiler because we declared dataConst as const thus restricting usage to safe methods // dataConst.setData(7); // this is allowed because we are not in safe method and data's interface allows unsafe calles data.setData(8); } }; Read More » Comment on GotW #4 Solution: Class Mechanics by Zenju
@Luca Risolia: This’s overkill, so it’s probably a good idea to concentrate on the most-used form, which is the temporary in the first argument for chains of operator +. For other classes, e.g. strings, this is all that’s ever needed, since operator + is not symmetric. Read More »Comment on C++ and Beyond: My material for December, and early-bird registration (through June 9) by S. Colcord
Missing link from last post: (http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#status.iso.2011) Read More »Comment on C++ and Beyond: My material for December, and early-bird registration (through June 9) by S. Colcord
@JC_Yang: Unfortunately, GNU is some distance from having a fully conforming standard library implementation (). This is ironically just the opposite of Visual C++, where the compiler is lacking, but the library is complete (to the extent it can be given the compiler). Read More »Comment on C++ and Beyond: My material for December, and early-bird registration (through June 9) by Natalie Welsh
Yes, MSVC2012 not supporting C++11 is really a pain in the ass. Now I am sitting here with MinGW and a Clang-Head checkout. Fine so far, but unfortunately it makes debugging the code a bit cumbersome, almost impossible. I can only hope that CodeLite or something similar can get things running. But that MSVC is so far behind is really embarassing. Why do you not just trash your compiler and integrate Clang into MSVC. That would be a lot better, and Clang officially needs Microsoft Extension support, so you could focus on that one… Kinda stupid to develop your own compiler these days. Clang is just perfect, no need for anything else… Read More »Comment on C++ and Beyond: My material for December, and early-bird registration (through June 9) by Herb Sutter
@Alex: Naturally, and I called my team out in my “GotW and Exceptional C++” post: http://herbsutter.com/2013/05/04/guru-of-the-week-and-the-exceptional-c-series/ (see the “preemptive snarky remark”). :) At the time we announced the November 2012 CTP, what we promised was to communicate further news in the first half of 2013, so we’re on the hook to say something no later than June 30. If July 1 dawns without that promise fulfilled, you can be approximately the 1000th person in line to slam me down on the mat and apply a scissors headlock while the 1001st person jumps down from the top rope to deliver a sledgehammer. Or something. I’m not very good with fake-wrestling analogies. Read More »Comment on C++ and Beyond: My material for December, and early-bird registration (through June 9) by Herb Sutter
@S. Colcord: Isn’t there a glaring omission from that libstdc++ C++11 conformance list? In particular, as of gcc 4.8 when I looked earlier this month, I believe their basic_string uses copy-on-write (COW). This has long been a bad idea in concurrent code for performance and correctness reasons (see my 1999 CUJ article http://www.gotw.ca/publications/optimizations.htm) and now is nonconforming in C++11 (breaks conforming user code). To conform to C++11, libstdc++ basic_string needs essentially a ground-up reimplementation, though they can probably salvage the code in most of the helper functions that should have been nonmembers in the standard — see GotW #84 at http://www.gotw.ca/gotw/084.htm. And BTW as I recently mentioned again in the recently revised GotW #2 at http://herbsutter.com/2013/05/13/gotw-2-solution-temporary-objects/, the libstdc++ maintainers should run, not walk, to add glorious SSO when they rip out odious COW. Not that I have any strong opinions on this or anything. Read More » | ||||
| ||||
Tuesday, May 28, 2013
FeedaMail: Comments for Sutterâs Mill
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment