Monday, September 2, 2019

Digest for comp.lang.c++@googlegroups.com - 25 updates in 6 topics

Frederick Gotham <cauldwell.thomas@gmail.com>: Sep 02 03:27AM -0700

> > try { p_children = &g_links.at(str_parent); } catch (...) { return; } // The method 'at' will throw if no such key exists in the map
 
> You shlouldn't catch this it is fatal error.
 
 
Are you saying that a 'map' object is unusable after a failed attempt to use 'at' ?
David Brown <david.brown@hesbynett.no>: Sep 02 09:58PM +0200

Please quote properly, without snipping attributions.
 
On 02/09/2019 12:27, Frederick Gotham wrote:
 
>> You shlouldn't catch this it is fatal error.
 
> Are you saying that a 'map' object is unusable after a failed attempt to use 'at' ?
 
I suspect he means that a failed "at" generally means you have a bug in
your code as you are trying to access something that doesn't exist. So
rather than catching the exception and trying to recover, you should use
the exception information as an aid to finding and fixing the bug.
Frederick Gotham <cauldwell.thomas@gmail.com>: Sep 02 03:30AM -0700

For the past 17 years, I've become accustomed to reading function declarations like this:
 
int MyFunc(double x);
 
I'm working on a project now though where there's function declarations like this:
 
int
MyFunc
(double x);
 
I've tried a few different code beautifiers and none of them can turn this into a one-liner.
 
Anyone got a tool for this?
Barry Schwarz <schwarzb@dqel.com>: Sep 02 11:25AM -0700

On Mon, 2 Sep 2019 03:30:31 -0700 (PDT), Frederick Gotham
> (double x);
 
>I've tried a few different code beautifiers and none of them can turn this into a one-liner.
 
>Anyone got a tool for this?
 
If you tell us which tools you have already tried, you might receive
more useful responses.
 
--
Remove del for email
Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 08:32PM +0200


> int
> MyFunc
> (double x);
 
I would acceppt any common style, but this is idiotic.
Richard Damon <Richard@Damon-Family.org>: Sep 02 11:12AM -0400

On 9/2/19 12:47 AM, Bonita Montero wrote:
>> maybe it is.
 
> We're not discussing about error handling or not;
> wer're discussing the performance-impacts.
 
Yes, we are talking about the performance impact of error handling.
 
>> requirements.
 
> You don't have any clue what you're talking about.
> You simply  fantasizing to emphasize your authority.
 
As an example, lets take sending data to the flight recorder in an
airplane. Errors may well occur during this operation (perhaps one log
fills so you need to switch to another). There may well be a piece of
this in the critical control loops. If an error delays the loop, then
perhaps some critical function fails, perhaps causing a loss of control
of the system.
 
Likely the critical control loop isn't directly communicating with the
flight recorder, but with an intermediary operation to provide some
buffering, but if the intermediary operation gets delayed too much in
sending the data to the flight recorder, it might not service the
control loop fast enough, causing the problems.
 
I don't work on airplanes (but I do work with real time systems), so
this exact case may not apply, but is a fairly graphic one which shows
that in a real time system, even errors need to be handled within time
limits. People who are used to 'PC' or 'Server' Class machines often
don't understand the real time world, On the PC 0.1 second response is
often good enough, maybe with a real-time interactive game it goes down
to 0.01 seconds, and not meeting that time mark is just a minor
'performance' issue. In a true real time system the time period is often
much shorter, and the cost of not meeting the time requirements are
often much more significant, something stopped working.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 05:52PM +0200

> this in the critical control loops. If an error delays the loop, then
> perhaps some critical function fails, perhaps causing a loss of control
> of the system.
 
Such systems have their critical resources allocated at startup that
those situations don't occur.
Manfred <noname@add.invalid>: Sep 02 06:43PM +0200

On 9/2/2019 5:52 PM, Bonita Montero wrote:
>> of the system.
 
> Such systems have their critical resources allocated at startup that
> those situations don't occur.
 
You really can't get it, can you?
Richard Damon <Richard@Damon-Family.org>: Sep 02 01:05PM -0400

On 9/2/19 11:52 AM, Bonita Montero wrote:
>> of the system.
 
> Such systems have their critical resources allocated at startup that
> those situations don't occur.
 
Out of Resources is not the only type of error that typcially generates
an exception. Some would have critical I/O errors be reported back as
exceptions (Remember the original discussion was Exceptions vs testing
return values). If one write in a billion might generate the error
condition, by many people that would be considered 'exceptional' and
properly done with an exception.
 
On a PC, if once every billion operations we got a slight additional
delay to the user, that would be normally acceptable. If that one in a
billion causes your airplane engine to stall in mid air, it wouldn't be.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 07:33PM +0200

> Out of Resources is not the only type of error that typcially generates
> an exception. Some would have critical I/O errors be reported back as
> exceptions ..
 
Have you considered the part of such an I/O-operation that might fail
is the kernel-call that has a higher processing-overhead than the error
-handling itself?
Juha Nieminen <nospam@thanks.invalid>: Sep 02 09:44AM

In C you can use designated initializers to initialize a struct
(or an array). There is no requirement for the order in which
the initializers are listed, so it's completely ok to list them
in a different order than they are declared in the struct.
So you can have:
 
struct S { int a, b; };
struct S s = { .b = 1, .a = 2 };
 
In C++20, however, you cannot list the initializers in the "wrong"
order.
 
Why?
 
It would be highly convenient that designated initializers wouldn't
need to be in the same order as the variables declared in the struct.
For example, the variables may be declared in one order in the struct
based on efficiency (the order of member variables may affect the
size of the struct), but listed in an initialization in another, eg.
grouped logically based on role.
 
Moreover, and more importantly, later changing the order of the
variables in the struct will not break the initialization (which I think
is one of the main motivations for it having been introduced in the
first place).
 
Why does C++20 impose this restriction?
 
I understand that C++ wants to initialize member variables in the order
they are declared inside the struct/class. However, I don't see why this
should affect designated initializers.
 
If listing the designated initializers in the "wrong" order is some kind
of problem when it comes to initialization values with side-effects, the
standard could simply state that if the designated initializers are not
listed in the same order as declared in the struct, the order of evaluation
of the values is not guaranteed and implementation-defined. However, it
doesn't need to outright forbid it. (After all, there are other situations
as well, where order of evaluation is not guaranteed, such as when giving
parameters to a function.)
 
I don't know what the C standard says about what happens when designated
initializers are not in the same order as in the declaration of the struct,
but at least clang seems to simply evaluate the values in the same order
as the latter, so it doesn't seem to be a problem.
James Kuyper <jameskuyper@alumni.caltech.edu>: Sep 02 10:20AM -0400

On 9/2/19 5:44 AM, Juha Nieminen wrote:
> struct S s = { .b = 1, .a = 2 };
 
> In C++20, however, you cannot list the initializers in the "wrong"
> order.
...
> I don't know what the C standard says about what happens when designated
> initializers are not in the same order as in the declaration of the struct,
 
I can't answer your other questions, but I can answer that one. This is
no such restriction in C on the order in which designators are written,
and here's what C2011 says about the order in which the resulting
initializations occur:
 
"... When no designations are present, subobjects of the current object
are initialized in order according to the type of the current object:
array elements in increasing subscript order, structure members in
declaration order, and the first named member of a union. In contrast, a
designation causes the following initializer to begin initialization of
the subobject described by the designator. Initialization then continues
forward in order, beginning with the next subobject after that described
by the designator." (6.7.8p17).
 
Thus, a designation causes a jump in the initialization order, after
which initialization moves forward as normal from the new position. You
could, as a result, end up initializing the same element or an array, or
the same member of a struct, multiple times. I would expect to see such
code only in the obfuscated C contest or in machine generated code, but
it is permitted.
Paavo Helde <myfirstname@osa.pri.ee>: Sep 02 05:25PM +0300

On 2.09.2019 12:44, Juha Nieminen wrote:
> initializers are not in the same order as in the declaration of the struct,
> but at least clang seems to simply evaluate the values in the same order
> as the latter, so it doesn't seem to be a problem.
 
So you propose that code pieces should be evaluated at a different order
than written. We already have a bad case of such silent code reordering
with the initialization lists, the committee probably did not want to
repeat that mishap.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 05:13PM +0200

> struct S s = { .b = 1, .a = 2 };
> In C++20, however, you cannot list the initializers in the "wrong"
> order.
 
I think this does help to read the initialization of a structure
because you can read it in the order as it is defined in the
structure. So if you read the initialization and have the defi-
nition open in another window, that's a more convenient read-
ability.
 
> based on efficiency (the order of member variables may affect the
> size of the struct), but listed in an initialization in another, eg.
> grouped logically based on role.
 
Convenience isn't determined in efficiency.
And if you won't have a POD you can't rely on a certain layout anyway.
 
> variables in the struct will not break the initialization (which
> I think is one of the main motivations for it having been introduced
> in the first place).
 
Ok, that's a proper reason; but as I said above, this would lead to
less readable code because the inizialization isn't synchronous with
the definition.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 08:33AM +0200


> read all...
> https://groups.google.com/forum/?hl=en#!original/comp.arch/JkcTGC9X3lo/M4Vo_cXKEwAJ
> Still, create a new post over on comp.arch
 
I further don't believe this; check this: https://bit.ly/2lprsvC
You won't find his full name this. I'm pretty sure that his full
name would be known you would easily google it; but you can't.
 
You have a very impulsive kind of thinking or you are very
impulsive at at all according to your posting-behaviour.
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 02 12:18AM -0700

On 9/1/2019 11:33 PM, Bonita Montero wrote:
> name would be known you would easily google it; but you can't.
 
> You have a very impulsive kind of thinking or you are very
> impulsive at at all according to your posting-behaviour.
 
Post over on comp.arch. Anne & Lynn Wheeler might still be watching it.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 09:23AM +0200

>> You have a very impulsive kind of thinking or you are very
>> impulsive at at all according to your posting-behaviour.
 
> Post over on comp.arch. Anne & Lynn Wheeler might still be watching it.
 
That's not necessary.
If there would be a definite name you could easily google it.
--
http://facebook.com/bonita.montero/
"Chris M. Thomasson" <chris.m.thomasson.1@gmail.com>: Sep 02 12:26AM -0700

On 9/2/2019 12:23 AM, Bonita Montero wrote:
 
>> Post over on comp.arch. Anne & Lynn Wheeler might still be watching it.
 
> That's not necessary.
> If there would be a definite name you could easily google it.
 
I cannot do it.
David Brown <david.brown@hesbynett.no>: Sep 02 01:13PM +0200

On 02/09/2019 07:16, Bonita Montero wrote:
 
>>> Maybe, but your style of response isn't mature.
 
>> Neither is deliberately snipping attributions...
 
> You're right. I will go to the psychotherapist because of that !!!!!!!!!
 
No, you won't. You will just be ignored.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 03:55PM +0200

>> You're right. I will go to the psychotherapist because of that !!!!!!!!!
 
> No, you won't. You will just be ignored.
 
That's your hope because you want this to be sanctioned.
But this won't fulfill.
woodbrian77@gmail.com: Sep 02 07:32AM -0700


> OK, you meant should a *message* be used (not a comment) in the static
> assertion (at least in C++17, where the message is now optional).
> Obviously it depends on the context.
 
OK. Thanks for the correction.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Sep 02 02:43PM

On Sun, 2019-09-01, Richard Damon wrote:
>> http://webEbenezer.net
 
> Personally, I would be tempted to leave it as is. Making useful error
> messages is generally good.
 
I have a thing against assert(condition, message) in general, so I'd
drop it, if
 
static_assert(std::numeric_limits<float>::is_iec559);
 
is likely to be meaningful to the reader, after some googling.
 
However, in an earlier discussion here, years ago, most didn't feel
that way.
 
> Making the Error comment optional might make
> some sense if the Error Condition is fully self documenting, but the
> linkage between IEC559 and IEEE754 isn't inherently obvious.
 
If it's hard to make the condition self-documenting, there should be a
message. Even I can agree to that.
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 08:56AM +0200

I posted some code here in the Rust-thread which measures the
performance of throwing an excetion. I made a mistake in the
first place because I didn't consider the slow-down of a x264
-thread on the same core. So the "performace" was a bit sur-
prising and a throw of an int took about 3 million clock-cycles.
As I ran it without any load a throw took about 8.6000 clock
-clycles on my Ryzen 7 1800X.
I told that I'm curious about the performance of other imple-
mentations (although this isn't really practically relevant).
I further improved my code to have two cases:
1. An exception of a base-class is trown and the base-class
is catched.
2. An exception of a class derived from a class derived from
the base-class is thrown and the base-class is catche. In
this case the difference in performance results from the
matching of the base-class.
Maybe some readers haven't read so deeply into the Rust-thread
so that only a few had read my posting. So I'm trying it for
a last time to encourage the readers to modify the code for
their compilers to get different results.
 
This is the common header:
 
#pragma once
#include <exception>
 
void BaseThrower();
void DerivedBThrower();
 
struct ExcBase : public std::exception
{
};
 
struct ExcDerivedA : public ExcBase
{
};
 
struct ExcDerivedB : public ExcDerivedA
{
};
 
This is the translation-unit with the trowing functions:
 
#include "exc.h"
 
void BaseThrower()
{
throw ExcBase();
}
 
void DerivedBThrower()
{
throw ExcDerivedB();
}
 
This is the main translation-unit:
 
#include <windows.h>
#include <iostream>
#include <intrin.h>
#include "exc.h"
 
using namespace std;
 
typedef long long LL;
LL Benchmark( void (*thrower)(), unsigned const rep );
 
int main()
{
// to get always the same TSC
SetThreadAffinityMask( GetCurrentThread(), 1 );
 
unsigned const REP = 1'000'000;
LL ticks;
 
ticks = Benchmark( BaseThrower, REP );
cout << "BaseThrower: " << (double)ticks / REP << endl;
 
ticks = Benchmark( DerivedBThrower, REP );
cout << "DerivedBThrower: " << (double)ticks / REP << endl;
}
 
LL Benchmark( void (*thrower)(), unsigned const rep )
{
LL start = (LL)__rdtsc();
for( unsigned i = rep; i; --i )
try
{
thrower();
}
catch( ExcBase & )
{
}
return (LL)__rdtsc() - start;
}
 
So I would be pleased about any results.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 09:02AM +0200

BTW: I know that actual CPUs support invariant time-stamp
-counters. So as the clock of the CPU might boost here the
TSC wouls still count at a constant rate.
But my code will still get a rough estimate of the overhead
throwing an exception.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 02 11:34AM +0200

I just modified the main source to be not dependent on Windows:
 
#include <iostream>
#include <intrin.h>
#include <chrono>
#include "exc.h"
 
using namespace std;
using namespace std::chrono;
 
typedef long long LL;
 
LL Benchmark( void (*thrower)(), unsigned const rep );
 
void SetAffinityToFirstThread();
 
int main()
{
unsigned const REP = 1'000'000;
LL ns;
 
ns = Benchmark( BaseThrower, REP );
cout << "BaseThrower: " << (double)ns / REP << "ns" << endl;
 
ns = Benchmark( DerivedBThrower, REP );
cout << "DerivedBThrower: " << (double)ns / REP << "ns" << endl;
}
 
LL Benchmark( void (*thrower)(), unsigned const rep )
{
time_point<high_resolution_clock> start = high_resolution_clock::now();
for( unsigned i = rep; i; --i )
try
{
thrower();
}
catch( ExcBase & )
{
}
return (LL)duration_cast<nanoseconds>( high_resolution_clock::now()
- start ).count();
}
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: