- peformance of wait notify concept of condition variable - 5 Updates
- Error message when defining a static data member - 1 Update
- How to do this (small task - std::transform?)? - 8 Updates
- Use of the break; and continue; statments - 3 Updates
- neoGFX wiki - 1 Update
- Pattern for message templates with DRY - 1 Update
- "Need for Speed - C++ versus Assembly Language" - 1 Update
- Use of the break; and continue; statments - 3 Updates
Bonita Montero <Bonita.Montero@gmail.com>: May 20 12:57PM +0200 > Where is this documented by Microsoft? I already wrote it in this thread, but here again: http://bit.ly/2qwJA7w |
Bonita Montero <Bonita.Montero@gmail.com>: May 20 12:59PM +0200 > then switch over to IOCP? Even in the IOCP mode, you make your code > fail when ReadFile returns TRUE: WHY? > This is just plain strange. I missed to wait for it. But fortunately this isn't a bug because file -extension is always done synchronously and WriteFile always returns TRUE in this case so there's no need to wait for the event. |
Bonita Montero <Bonita.Montero@gmail.com>: May 20 01:00PM +0200 > Okay. But, can you be 100% sure that the async IO file never will give > an async result? How? Yes, extending a file is always synchronous. |
"Chris M. Thomasson" <invalid@invalid.invalid>: May 20 10:30AM -0700 On 5/20/2017 3:59 AM, Bonita Montero wrote: > I missed to wait for it. But fortunately this isn't a bug because file > -extension is always done synchronously and WriteFile always returns > TRUE in this case so there's no need to wait for the event. I see. |
"Chris M. Thomasson" <invalid@invalid.invalid>: May 20 12:46PM -0700 On 5/20/2017 3:57 AM, Bonita Montero wrote: >> Where is this documented by Microsoft? > I already wrote it in this thread, but here again: http://bit.ly/2qwJA7w Got it Bonita. Btw, thank you for conversing with me. I think this thread can come to and end now. |
Dombo <dombo@disposable.invalid>: May 20 09:26PM +0200 Op 11-May-17 om 8:46 schreef David Brown: > will be heavily outweighed by people using "using" to minimise the need > for ::, rather than people who add it superfluously. It is definitely > atypical. As a contractor I've worked for many organizations, and I have never seen the leading "::" used or recommended as a coding style. The use of superfluous colons would be frowned upon at the very least, and more likely would would lead to a reject when the code is reviewed. The C++ syntax is already noisy enough as it is; there is no point in making the code even harder to read. The question of the TS illustrates why the superfluous colons are a bad idea. It surprises me that some of the people here seem to go out of their way to write obfuscated code and then ask for help. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 20 02:34AM +0200 On 19-May-17 5:14 PM, JiiPee wrote: > // add 10 items into persons2 .... > Now, which std-function I can use to copy *only* the age-values from > persons vector into persons2? for( int i = 0, n = persons.size(); i < n; ++i ) { persons2[i].age = persons[i].age; } > I was thinking using std::transform, but could not yet find how. I need > to use some other std function? No. I recommend just a simple, clear loop as above. Perhaps with an `assert` that the vectors are of equal size. > I know how to do it with a for-loop of course, but would like to know > how to do it with std-functions. Oh. There's no suitable such function. It would be contrived. Cheers & hth., - Alf |
JiiPee <no@notvalid.com>: May 20 04:03AM +0100 On 20/05/2017 01:34, Alf P. Steinbach wrote: > { > persons2[i].age = persons[i].age; > } sure, ok so not good to even consider functions. But it was good to know by Stefan how to do it anyway. you dont prefer: for( size_type i{0}, size = persons.size(); i < size; ++i ) ? |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 20 05:46AM +0200 On 20-May-17 5:03 AM, JiiPee wrote: > you dont prefer: > for( size_type i{0}, size = persons.size(); i < size; ++i ) > ? Using a modulo-2^n arithmetic type for a general integer, as opposed to for bit-level operations, is ungood in itself. Mainly because the promotion rules in modern C++ then are likely to cause unintended and un-noticed wrap-around promotions that cause havoc. My usual example is that the expression `string( "Bah!" ).length() < -5` is true. Doing the unfortunately not uncommon dance with trying to use the minimal unsigned type is an additional abomination on top of the first, adding needless extra work up front, in addition to the extra work later on for sorting out the bugs from the modulo-2^n behavior. As I see it, just use appropriate simple types and appropriate simple constructs, and don't try to be fancy. BUT: if the vector can have more than 2G entries, then make sure to use an index type that can deal with that, such as `ptrdiff_t`. If you use that by default then you're safe at almost no cost. So it can be a good idea to define self-describing names for it, e.g. `Size` and `Index`. Summing up: a modulo-2^n type does not yield shorter code, has no advantage, and due to modern C++ promotion rules that practice can and will bite you in the rear end at the least convenient moment. Cheers!, - Alf |
JiiPee <no@notvalid.com>: May 20 06:32PM +0100 On 20/05/2017 04:46, Alf P. Steinbach wrote: > Summing up: a modulo-2^n type does not yield shorter code, has no > advantage, and due to modern C++ promotion rules that practice can and > will bite you in the rear end at the least convenient moment. Sure, also Bjarne said similar things (he does not like uint). But how about that int i{0}; ? the way to initialize int? rather than int i = 0; |
Bonita Montero <Bonita.Montero@gmail.com>: May 20 07:57PM +0200 With std::transform ... #include <string> #include <vector> #include <algorithm> using namespace std; struct Person { int age; string name; }; struct Person2 { int age; int height; string name; string mobilenumber; }; void f( vector<Person> &vp, vector<Person2> &vp2 ) { vp2.reserve( vp.size() ); transform( vp.begin(), vp.end(), back_inserter( vp2 ), []( Person &p ) { Person2 p2; p2.age = p.age; return p2; } ); } |
Cholo Lennon <chololennon@hotmail.com>: May 20 04:01PM -0300 On 05/20/2017 02:57 PM, Bonita Montero wrote: > transform( vp.begin(), vp.end(), back_inserter( vp2 ), > []( Person &p ) { Person2 p2; p2.age = p.age; return p2; } ); > } +1, the best solution IMO (and kudos for showing the usage pattern: reserve for vectors, transform/back_inserter) -- Cholo Lennon Bs.As. ARG |
Bonita Montero <Bonita.Montero@gmail.com>: May 20 09:02PM +0200 > ::std::cout << '\n'; } Not '\n' but endl. endl is flushing the stream. And your formatting-style is disgusting. |
JiiPee <no@notvalid.com>: May 20 08:09PM +0100 On 20/05/2017 19:30, Stefan Ram wrote: >> int i{0}; >> int i = 0; > In the first case, narrowing is forbidden, and it is the but we dont need narrowing here. int to int.. zero is int. > (since C++17). However, a zero initialization can also be > written more concise as > int i {}; for me int i{0}; is clearer because we see clearer that i starts from 0 in that for loop. |
ram@zedat.fu-berlin.de (Stefan Ram): May 20 09:40AM >In the private sector I identified a need to focus and teach error >handling, in particular use of exceptions, up front, »Many people taught - and some continue to teach - C++ as either a very low-level language with a focus on features shared with C, or as a language for expressing class hierarchies. Both approaches fail to emphasize C++'s greatest strengths. Worse: such approaches often spend so much time on parts of C++ that are not very supportive of programmers that they fail to teach facilities and techniques critical to effective use of C++. The standard library containers and algorithms and the use of exceptions in resource management are examples of key topics that are often neglected, or wrongly considered advanced.« - Bjarne Stroustrup |
ram@zedat.fu-berlin.de (Stefan Ram): May 20 10:38AM >relearn a lot about programming when they start working, is that at >university/college they learn a kind of idealized programming world, one >where nothing ever fails, hence only the simplest error handling. For library-grade software (as I call it), in C, error handling means being very fussy about checking the result of most function calls and operations. This will become very visible in C and will essentially dictate the structure of the program and can make up 80 % of the code. In C++ it is something else, because so many things happen undercover. Exceptions control the flow in an invisible manner (www.gotw.ca/gotw/020.htm), and RAII then releases resources in an invisble manner (008.htm, 056.html, 059.htm, 082.html, herbsutter.com/gotw/_102/, and others). So, a C++ program that was carefully crafted by a master to handle all errors and release all resources correctly might look to a beginner as if the author did not care about theses topics at all. |
ram@zedat.fu-berlin.de (Stefan Ram): May 20 06:30PM >int i{0}; >int i = 0; In the first case, narrowing is forbidden, and it is the "/uniform/ initialization syntax". Another possibility is auto i{ 0 }; (since C++17). However, a zero initialization can also be written more concise as int i {}; . |
fir <profesor.fir@gmail.com>: May 20 02:33AM -0700 W dniu sobota, 20 maja 2017 01:08:22 UTC+2 użytkownik Rick C. Hodgin napisał: > fir, I wrote a couple lines on it. Perhaps you could set aside your > negativity toward me and learn something. perhaps you can rely on my kick in your abusing dumb bad idiot ass |
Marcel Mueller <news.5.maazl@spamgourmet.org>: May 20 11:24AM +0200 Hello! From time to time I have the requirement to declare all messages that an application can create at a central place. Unfortunately this usually requires to do changes at up to 4 different locations in C++ to add a single message. This is contradictory to the DRY rule. Example: #include <iostream> #include <set> #include <array> #include <algorithm> using namespace std; struct MsgTemplate { int ID; const char* TextTemplate; }; struct Message { int ID; string Text; // Normally we should accept message arguments and // do some formatting together with the text template. // But let's ignore this for now. Message(MsgTemplate tpl) : ID(tpl.ID), Text(tpl.TextTemplate) {} }; struct MyWorker { // 1st location (header file) static constexpr const MsgTemplate WARN_SOMETHING_WENT_WRONG = { 1001, "Something went wrong" }; static constexpr const MsgTemplate ERR_SOMETHING_WENT_REALLY_WRONG = { 1002, "Something went really wrong" }; static constexpr const MsgTemplate ERR_INVALID_MSGID = { 2001, "Invalid message ID" }; // 2nd location (header file) static constexpr const array<const MsgTemplate*,3> AllMessages = {{&WARN_SOMETHING_WENT_WRONG, &ERR_SOMETHING_WENT_REALLY_WRONG, &ERR_INVALID_MSGID }}; set<int> MessageFilter; void AddFilter(int id) { if (!any_of(AllMessages.begin(), AllMessages.end(), [id](const MsgTemplate* mp) -> bool { return mp->ID == id; })) Print(Message(ERR_INVALID_MSGID)); else MessageFilter.emplace(id); } void Print(const Message& msg) const { if (MessageFilter.find(msg.ID) == MessageFilter.end()) cout << msg.ID << '\t' << msg.Text << endl; } void Foo() { Print(Message(WARN_SOMETHING_WENT_WRONG)); throw Message(ERR_SOMETHING_WENT_REALLY_WRONG); } }; // 3nd location (source file) constexpr const MsgTemplate MyWorker::WARN_SOMETHING_WENT_WRONG; constexpr const MsgTemplate MyWorker::ERR_SOMETHING_WENT_REALLY_WRONG; constexpr const MsgTemplate MyWorker::ERR_INVALID_MSGID; // 4th location (source file, total count) constexpr const array<const MsgTemplate*,3> MyWorker::AllMessages; int main(int argc, char** argv) { MyWorker worker; while (*++argv) worker.AddFilter(atoi(*argv)); try { worker.Foo(); } catch (const Message& msg) { switch (msg.ID) {case MyWorker::ERR_SOMETHING_WENT_REALLY_WRONG.ID: cout << "Caught ERR_SOMETHING_WENT_REALLY_WRONG\n"; break; default: worker.Print(msg); } return msg.ID; } return 0; } The above example demonstrates the main requirements: - Each message template has a (unique) ID. - Each message template has a symbol name in the code. - There is a list of all possible messages. - Messages could be dispatched by ID with a switch statement. Until now I always ended up by some Perl script that created the code files from a common XML source or something like that. Now I try to figure out what is possible with C++11. But, as you can see, I did not get that far. I am also confused because I need to define the static constexpr members additionally in the source code to avoid linker errors. I would have expected that the constexpr MsgTemplate fields would expand to constants at the place where the messages are constructed by the inline constructor, as it obviously works at the place switch(msg.ID). Any ideas for a better design? The above example is awful. I already tried to define only the global array with all message templates and define constexpr symbol names to the array elements. This removes some redundancy. But it is error prone to assign the symbol names because the array elements can only be accessed by index. Marcel |
Lynn McGuire <lynnmcguire5@gmail.com>: May 20 12:12AM -0500 On 5/15/2017 11:20 PM, Alf P. Steinbach wrote: > And I'm not. :( > Cheers!, > - Alf I need to speed up my own code. Lynn |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 20 02:41AM +0200 On 20-May-17 1:04 AM, Tim Rentsch wrote: > [snipped very much] Two of the examples you gave > for 'break' (with a 'found' flag, and code duplication), ran > counter to what I expected. [snipped very much] I think this de-emphasis, this hiding away of those two concrete issues, is wrong and wrong-headed. Concrete advice about concrete situations affects the behavior the most, has the most impact. Abstract advice is nice but needs to build on a concrete foundation of examples, even if it maybe sounds more impressive. Cheers!, - Alf |
Tim Rentsch <txr@alumni.caltech.edu>: May 19 05:59PM -0700 > situations affects the behavior the most, has the most > impact. Abstract advice is nice but needs to build on a concrete > foundation of examples, even if it maybe sounds more impressive. I didn't (and still don't) consider them the high-order bits of what I was saying. Also I thought it would be counter-productive to get into a style debate, especially since I wasn't trying to say that either approach was better, only that what he said isn't what I would have expected. You are welcome to re-write the comments in my posting to say what I was saying in a way you think would be more effective. If you do I look forward to reading it. |
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: May 20 04:11AM +0200 On 20-May-17 2:59 AM, Tim Rentsch wrote: > to get into a style debate, especially since I wasn't trying to > say that either approach was better, only that what he said isn't > what I would have expected. So the ~5000 characters you wrote about abstract considerations of style for loops (essentially, minimize use of break and continue), and that there are other things to learn about in a general programming curriculum, was not, in your opinion, about style issues. But concrete examples showing how to duplicate code and add complication such as success flag, on ideological grounds, are in your opinion "minor points of style". IMO that's plain wrong, and it's a wrong-headed approach; sorry. I'm not saying that style isn't important. I'm saying that I think the de-emphasis is entirely wrong; that the general approach of not actually addressing the concrete contents of the OP's posting is wrong, even if it sounds nice; and also that the apparent idea that all style issues are unimportant, is wrong. > You are welcome to re-write the comments in my posting to say > what I was saying in a way you think would be more effective. > If you do I look forward to reading it. I wouldn't write that as a response to the OP's posting. A general discussion of how to teach programming would involve much more. And I'm much less sure than you appear to be, about what /is/ a good approach or weighting of issues. I have extensive experience teaching programming and software development in general, in vocational school, at college, and in Accenture (a large consulting firm). And as I learned more about teaching and how understanding of programming develops in people, I became less and less sure about what should be early topics and what constituted advanced, later stuff. I read what you wrote as promoting an early focus on functional decomposition. That's nice, but it's just one aspect. In the private sector I identified a need to focus and teach error handling, in particular use of exceptions, up front, because just about every consultant had incorrect ideas about it. They'd write ugly try-catch-finallies in Java, one in every function, and the designs would be complicated and full of redundancy. Some would complain if an exception was allowed to just propagate instead of taking a detour through a try-catch-finally in every stack frame. I still believe that one main reason students fresh from college have to relearn a lot about programming when they start working, is that at university/college they learn a kind of idealized programming world, one where nothing ever fails, hence only the simplest error handling. At the time, the late 1990's and early 2000's, DBC (Design By Contract) was very much in vogue and I thought that was a good idea. It would be in line with your idea of functional decomposition as a main early topic. For simple loops it's about loop invariants and variants; for functional decomposition it's about preconditiom requirements and postcondition guarantees (which is where it intersects with exceptions and error handling); and for classes it's about class invariants. But the problems adding DBC support to C++, that proposal just failed, while e.g. Eiffel has working DBC support, showed that DBC was much less practical, much less generally applicable, than I believed. It's possible that systematic teaching experiments are needed, for the way that I formulated /ad hoc/ impressions from my teaching experience, seems inadequate: I still don't know clearly enough what's bad and what's good. Still I would warn against too strong an emphasis on functional decomposition, especially top-down stepwise refinement, since that's strongly tied to the waterfall development process, which is a sure way to end up with low quality over budget and over time. Make the most important decisions affecting the most, when you know the least. On the third hand, /naming/ things can probably not be emphasized too much, and functional decomposition, naming actions, is a special case of that. Cheers!, - Alf |
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