Saturday, May 20, 2017

Digest for comp.lang.c++@googlegroups.com - 23 updates in 8 topics

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: