Tuesday, September 3, 2019

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

Juha Nieminen <nospam@thanks.invalid>: Sep 03 02:07PM

> 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.
 
I don't really care in which order the parameters are evaluated and the
elements initialized. The standard could just as well say that if the
designated initializers are not listed in the same order as they are
declared in the struct, then the order of evaluation and initialization
is implementation-defined, and allow the compiler do whatever it wants
with respect to that order.
Juha Nieminen <nospam@thanks.invalid>: Sep 03 02:14PM

> 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.
 
I don't think it would lead to less readable code.
 
The members of a struct may be declared in an "illogical" order because
of efficiency reasons. The order of these elements may affect the size
of the struct (grouping small elements may make the struct smaller,
compared to the situation where large and small elements are declared
in alternation).
 
However, in an initialization you may want to list the elements in a
more logical order, eg. based on role or meaning. For example if two
members are closely related, you may want to list them consecutively
in the initialization (even if they aren't consecutive inside the
struct, for space efficiency reasons).
 
And, of course, as said, if you ever change the order of the member
variables (eg. to optimize the size of the struct), it wouldn't break
designated initializers.
Richard Damon <Richard@Damon-Family.org>: Sep 02 05:16PM -0400

On 9/2/19 1:33 PM, Bonita Montero wrote:
 
> 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?
 
Kernel, what kernel. From my experience, most of the truly real time
systems have nothing remotely like a *nix or Windows kernel anywhere in
them. They are running on machines much smaller than your typical X86
processor which is focused on a particular job. I/O operations are quick
an efficient, and there isn't the heavy security isolation of a large
monolithic operating system.
 
People whose world is all monolithic OS machines, with heavy isolation
between processes and high costs of context switches to do many things
may have trouble understanding the very different world of the smallish
processor running much closer to bare metal to get the job done quickly,
efficiently, and ON TIME. Different problems need different sorts of
solutions which have different types of environments that they run under.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 03 06:49AM +0200


> Kernel, what kernel. From my experience, most of the truly real time
> systems have nothing remotely like a *nix or Windows kernel anywhere
> in them.
 
He was talking about flight-computers. And almost every flight-computer
uses VxWorks.
And you don't have any "experience" on that.
David Brown <david.brown@hesbynett.no>: Sep 03 08:31AM +0200

On 03/09/2019 06:49, Bonita Montero wrote:
>> in them.
 
> He was talking about flight-computers. And almost every flight-computer
> uses VxWorks.
 
No, they don't.
 
VxWorks is certainly a possible option for flight computers, but it is
by no means dominant. Indeed, /no/ OS is dominant for such uses - you
use redundant systems with different software and hardware.
 
And he was talking about flight recorders (black boxes), not flight
computers.
 
> And you don't have any "experience" on that.
 
Nor do you. The difference is, others understand their experiences and
limitations, understand the differences in various fields of
programming, and try to expand their knowledge beyond their fields (even
when they never actually work on those systems). They don't extrapolate
wildly from one small area of software, and they don't make wild claims
with no evidence or reference.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 03 08:39AM +0200

> when they never actually work on those systems).  They don't extrapolate
> wildly from one small area of software, and they don't make wild claims
> with no evidence or reference.
 
No one here has experience with systems where they think exception
-handling should be inappropriate for performance-reasons; that's
all pure phantasy.
David Brown <david.brown@hesbynett.no>: Sep 03 09:06AM +0200

On 03/09/2019 08:39, Bonita Montero wrote:
 
> No one here has experience with systems where they think exception
> -handling should be inappropriate for performance-reasons; that's
> all pure phantasy.
 
Sorry, you are wrong again. I have worked on several systems where
exception handling would have been ruled out for performance reasons
(had the software been written in C++, rather than C). They would have
been ruled out of those projects for several reasons, in fact -
exceptions are often not suitable where you have tight safety
requirements. (You'll be shocked to hear that dynamic memory is also
banned in such software.)
 
For most of my C++ projects, exceptions are not used at all. It would
simply be unacceptable for there to be errors where throwing an
exception could be at all useful - therefore any exception support is
pure overhead, and they are disabled at the tool level.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 03 09:19AM +0200

> Sorry, you are wrong again. I have worked on several systems where
> exception handling would have been ruled out for performance reasons
> (had the software been written in C++, rather than C).
 
I don't believe you.
David Brown <david.brown@hesbynett.no>: Sep 03 10:30AM +0200

On 03/09/2019 09:19, Bonita Montero wrote:
>> exception handling would have been ruled out for performance reasons
>> (had the software been written in C++, rather than C).
 
> I don't believe you.
 
I don't care.
Richard Damon <Richard@Damon-Family.org>: Sep 03 07:11AM -0400

On 9/3/19 3:19 AM, Bonita Montero wrote:
>> exception handling would have been ruled out for performance reasons
>> (had the software been written in C++, rather than C).
 
> I don't believe you.
 
The fact that you haven't encountered significantly tight real-time
requirements doesn't mean they don't exist. I can say from experience
that there ARE cases with rules like this, and they have good grounds to
exist.
 
Exceptions work in many environments, but not all. Error code returns
work in many environments too. Which methods are usable, and which
methods are good to use, and which method is best, are VERY subject to
the domain you are working in. To think that one method is best
everywhere is very myopic, and says that one has been in just a small
part of the total space of programming.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 03 01:17PM +0200

>> I don't believe you.
 
> The fact that you haven't encountered significantly tight real-time
> requirements doesn't mean they don't exist.
 
The folks here are Nerds without any experience on that. And if there
are any circumstances that would make error-handling through exception
not feasible because they would be too slow, this would be very rare.
Thus it is not credible that david would have many of such experiences.
He is simply a liar!
David Brown <david.brown@hesbynett.no>: Sep 03 03:29PM +0200

On 03/09/2019 13:17, Bonita Montero wrote:
 
>> The fact that you haven't encountered significantly tight real-time
>> requirements doesn't mean they don't exist.
 
> The folks here are Nerds without any experience on that.
 
And you base that on what evidence?
 
There are people in this group with experience of all sorts of systems.
There are people who have programmed tiny systems. My own record for
small devices was 1K flash and no ram (programmed in C with gcc). I
have a project coming up with 2K flash and 128 byte ram on the device.
 
There are people here who have programmed mainframes, supercomputers,
operating systems, hypervisors, games, simulators, emulators,
programming languages. There are people who have programmed
safety-critical systems or high reliability systems (I have personally
worked on a couple of systems where mistakes could cost lives, and
several more where mistakes cost millions. I know I am not alone in
that in this group). And of course there are also those who have "only"
worked on PC software, or who are students, or hobby programmers, or
academics.
 
> And if there
> are any circumstances that would make error-handling  through exception
> not feasible because they would be too slow, this would be very rare.
 
No one has denied that it is unusual for the speed of exceptions to be
the reason they can't be used in a project. It is far, far more
important that the speed is unpredictable and you cannot (with any sane
level of effort) be sure of the limits. You don't understand what "real
time" means - please try to learn a little from other people, rather
than parading your ignorance.
 
> Thus it is not credible that david would have many of such experiences.
> He is simply a liar!
 
Really? You have extrapolated from your own experiences and limited
knowledge, and made wild and unjustified comments about programming
domains well beyond your ken. You combine that with continuous and
apparently wilful misreading of my posts, and that's your conclusion?
 
So tell me, /why/ do you think I am lying? Do you think I am trying to
appear impressive and gain respect? From whom? The people in this
group whose opinion I respect are not impressed by lies or
exaggerations, and are usually quite good at spotting them. It should
be quite obvious that I have little respect for /you/ at the moment, and
therefore no interest in trying to impress you.
 
My interest in this discussion has been about sharing experiences and
knowledge, and perhaps giving people something to think about or some
ideas of programming issues beyond those that are familiar to them from
before, and maybe correcting some misconceptions. That is usually what
I look for myself in discussion threads.
 
It is painfully clear, however, that you are unteachable - your reaction
to being shown something new is denial and insults. This is a shame,
and I hope you will realise it and make an effort to change.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 03 03:42PM +0200

Liar!
Bonita Montero <Bonita.Montero@gmail.com>: Sep 03 03:51PM +0200

You try to emphasize your credibility as a developer who ewas involved
in a lot projects like those I told by referring to others her in this
group that have similar special positions. How stupid is that?
Richard Damon <Richard@Damon-Family.org>: Sep 02 05:40PM -0400

>> text space in the file and virtually zero processing time during
>> compilation. Treat it as file documentation for the requirements of the
>> system, and make it readable.
 
The one purpose of IEC559 in the message is that that is what the
language calls it, so including it in the message might be useful.
 
My main thought is why work hard to coming up with a minimal message
when there is NO run time cost to the fuller message. The string
shouldn't even be included in the image, as static_assert generates no
code. Yes, the message may be never seen, but if it IS seen, it would
seem best to make it clear. The expected output (but I don't think
required) is printing the message, and maybe the condition that was
false as part of the error message. My preference would be that the
message be fairly self explanatory by itself.
 
Yes, they can go to the source code to read a comment near by, and maybe
even that happens somewhat automatically if they are building in an IDE,
but the less you assume about the environment, the better for the user.
If the message is clear, the user might realize without needing to dig
into the code, that they need to invoke the build with a flag to use IEC559.
 
It would be nice if in the vicinity of the static_assert was some
comments explaining WHY you have such a statement in the code, in case
someone on a machine that doesn't support it tries to use it, so they
can figure out if they want to try to remove the assumptions in the code
or if they need to try to find another package.
James Kuyper <jameskuyper@alumni.caltech.edu>: Sep 02 10:53PM -0400

On 9/2/19 5:40 PM, Richard Damon wrote:
> On 9/1/19 9:58 PM, woodbrian77@gmail.com wrote:
>> On Sunday, September 1, 2019 at 2:39:57 PM UTC-5, Richard Damon wrote:
...
>>> linkage between IEC559 and IEEE754 isn't inherently obvious.
...
>>> even extend the error message to something more verbose, like
 
>>> IEEE754/IEC559 Floating point assumed and needed
 
>> I don't like having iec559 in there. If they want
...
> The one purpose of IEC559 in the message is that that is what the
> language calls it, so including it in the message might be useful.
 
The language calls it that as an abbreviation for IEC/ISO/IEEE 60559,
which is what IEC, ISO, and IEEE all call it. I'd normally provide a
message using the unabbreviated name: "IEC/ISO/IEEE 60559 (== IEEE 754)
floating point assumed and needed."
David Brown <david.brown@hesbynett.no>: Sep 03 08:21AM +0200

On 02/09/2019 23:40, Richard Damon wrote:
> someone on a machine that doesn't support it tries to use it, so they
> can figure out if they want to try to remove the assumptions in the code
> or if they need to try to find another package.
 
As a follow-on from that, remember that static assertions are free in
the code, document requirements, and protect from unwarranted
assumptions. So it is fine to duplicate them. If you have a library
file with twenty mathematical functions, and three of them rely on IEEE
formats for some reason, put the static assertion at all three
functions. And the message can explain /why/ the assertion is there,
although that could also be left in comments in the code.
 
static_assert(std::numeric_limits<float>::is_iec559,
"IEEE format is needed for exponent hack in log_base2");
double log_base2(double x)
{
...
}
David Brown <david.brown@hesbynett.no>: Sep 03 08:25AM +0200


> a. remove the comment
> b. reduce the comment to just "IEEE754", or
> c. leave it as it is.
 
The static_assert message is what users see when the assertion fails.
That is your guide.
 
If the check itself is information enough, you don't need a message. If
it is not clear (perhaps users don't know what "is_iec559" means - but
/would/ know what "IEEE format floating point" means), use a message.
 
You can also use it to give more detail of /why/ the assertion is there
- "IEEE floating point required to ensure binary compatibility", or
"Only tested with IEEE floating point format". Then the user can get an
idea of the reasoning for the assertion, and the consequences of
removing it (will it break something, or is it merely untested?).
Keith Thompson <kst-u@mib.org>: Sep 03 12:35AM -0700

David Brown <david.brown@hesbynett.no> writes:
[...]
> The static_assert message is what users see when the assertion fails.
> That is your guide.
 
For certain values of "users". The message is seen when the code is
compiled. For most software, most end users use precompiled
executables.
 
[...]
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
David Brown <david.brown@hesbynett.no>: Sep 03 10:31AM +0200

On 03/09/2019 09:35, Keith Thompson wrote:
 
> For certain values of "users". The message is seen when the code is
> compiled. For most software, most end users use precompiled
> executables.
 
Yes. By "users", I mean "users of the source code" rather than "users
of the resulting binaries".
Pavel <pauldontspamtolk@removeyourself.dontspam.yahoo>: Sep 02 09:41PM -0400

Trying to write generic code for forwarding arguments via a template
method to methods defined in an interface precisely (in particular, all
references should be forwarded as references and values as values).
Using gcc 4.8.5 and -std=c++11 (cannot change). The best code I could
come up with so far is below.
 
Taking the below code as an example, I want generated `callMethod' to
have exactly same last 2 parameter types as the interface method it
calls ((I,I) for ma, (const I&, const I&) for mb and (const I&, I) for
mc). The below code generates, according to nm output,
 
void Caller<IA, 1>::callMethod<void (IA::*)(I, I), I const&, I
const&>(void (IA::*)(I, I), I const&, I const&)
void Caller<IA, 2>::callMethod<void (IA::*)(I const&, I const&), I&,
I&>(void (IA::*)(I const&, I const&), I&, I&)
void Caller<IA, 3>::callMethod<void (IA::*)(I const&, I), I const&, I
const&>(void (IA::*)(I const&, I), I const&, I const&)
 
commented implementations of callMethod are also failed tries (the last
one passes all Is to callMethod by value, the first two do not compile
at least one of the instantiations).
 
Any ideas? (gcc 4.8.5 / -std=c++11 is of utmost interest but any working
configuration would help)
 
TIA,
-Pavel
 
-----------
#include <iostream>
#include <functional>
using namespace std;
 
struct I;
ostream& operator<<(ostream&, const I&);
struct I {
int i_;
I(int i): i_(i) {}
I(const I& i): i_(i.i_) {
cout << "I(c&" << i << ")\n";
}
I(I&& i): i_(i.i_) {
cout << "I(&&" << i << ")\n";
}
};
ostream&
operator<<(ostream& os, const I& i) { return os << i.i_; }
 
struct IA {
virtual void ma(I, I) = 0;
virtual void mb(const I&, const I&) = 0;
virtual void mc(const I&, I) = 0;
};
 
template <class T, const int> // second parameter is to
// distinguish the prototypesin nm output with certainty
struct Caller {
Caller(T& to): o(to) {}
T& o;
/*
template<class... A>
void callMethod(void (T::*m)(A...), A&&... args) {
(o.*m)(forward<A>(args)...);
}
template<class... A>
void callMethod(void (T::*m)(A...), A... args) {
(o.*m)(args...);
}
template<class M, class... A>
void callMethod(M m, A... args) {
(o.*m)(args...);
}
*/
template<class M, class... A>
void callMethod(M m, A&&... args) {
(o.*m)(forward<A>(args)...);
}
};
 
struct A: public IA {
void ma(I, I) override
{ cout << "A::ma(I, I)\n"; }
void mb(const I&, const I&) override
{ cout << "A::mb(const I& , const I&)\n"; }
void mc(const I&, I) override
{ cout << "A::mc(const I& , I)\n"; }
};
 
int
main(int, char*[])
{
A a;
const I i1{1};
const I i2{2};
I i3{3};
I i4{4};
const I i5{5};
const I i6{6};
Caller<IA, 1>(a).callMethod(&IA::ma, i1, i2);
Caller<IA, 2>(a).callMethod(&IA::mb, i3, i4);
Caller<IA, 3>(a).callMethod(&IA::mc, i5, i6);
return 0;
}
-----------
"Öö Tiib" <ootiib@hot.ee>: Sep 03 12:24AM -0700

On Tuesday, 3 September 2019 04:41:51 UTC+3, Pavel wrote:
 
> Any ideas? (gcc 4.8.5 / -std=c++11 is of utmost interest but any working
> configuration would help)
 
What was the question or issue? Did read 3 times over but somehow missed
it. :( Perhaps I need a coffee.
Bonita Montero <Bonita.Montero@gmail.com>: Sep 03 07:15AM +0200

I just put everything together in one file. And as the benchmark
is called with a function-pointer twice inteprocedural optimiza-
tions aren't really needed anymore to prevent the compiler from
optimizing away the throw.
I compiled this with an older gcc and found, that gcc is about
42% faster when trowing an exception; and theres a big differnece
to VC++ because it takes almost the same time cathing a derived
exception than catching the base-exception.
 
#include <iostream>
#include <chrono>
#include <exception>
 
using namespace std;
using namespace std::chrono;
 
struct ExcBase : public exception
{
};
 
struct ExcDerivedA : public ExcBase
{
};
 
struct ExcDerivedB : public ExcDerivedA
{
};
 
typedef long long LL;
 
void BaseThrower();
void DerivedBThrower();
LL Benchmark( void (*thrower)(), unsigned const rep );
 
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();
}
 
void BaseThrower()
{
throw ExcBase();
}
 
void DerivedBThrower()
{
throw ExcDerivedB();
}
Keith Thompson <kst-u@mib.org>: Sep 02 03:06PM -0700


> 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?
 
Are most or all function declarations in the project like that? Is it
part of the style guide for the project? If so, consider leaving it
alone.
 
I've seen styles that require function names to be at the beginning of
the line.
 
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */
Louis Krupp <lkrupp@nospam.pssw.com.invalid>: Sep 02 10:04PM -0600

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?
 
Pipe the source files one at a time through:
 
===
#!/bin/bash
 
perl -0777 -pe 's/(\w)\s*\n\s*(\()/$1$2/g'
===
 
It turns this:
 
===
int
MyFunc1
(double x);
 
int
MyFunc1a
(double x);
 
int
MyFunc2 (double x);
 
void s1(void)
{
int a = 7 +
(8);
}
 
void s2(void)
{
int a = MyFunc1
(8);
}
 
===
 
into this:
 
===
int
MyFunc1(double x);
 
int
MyFunc1a(double x);
 
int
MyFunc2 (double x);
 
void s1(void)
{
int a = 7 +
(8);
}
 
void s2(void)
{
int a = MyFunc1
(8);
}
===
 
Try it. It might make things better. Or it might make them much, much
worse.
 
Louis
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: