Monday, March 7, 2016

Digest for comp.lang.c++@googlegroups.com - 11 updates in 4 topics

Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 07 10:07PM

C++ exceptions are broken.
 
As it currently stands a more serious std::logic_error exception can be
downgraded into a less serious std::runtime_error exception if an
exception is thrown whilst evaluating the throw expression. This is a
nonsense.
 
Fix: if an exception is thrown whilst evaluating a throw expression then
std::terminate() is called.
 
/Flibble
Paavo Helde <myfirstname@osa.pri.ee>: Mar 07 10:21AM +0200

On 6.03.2016 22:43, bartekltg wrote:
> // always x >= 2 because M[0] and M[1] created in the
> constructor.
> M[x] = this->operator ()(x-1) + this->operator ()(x-2);
 
From the key type uint64_t I infer that this is meant to support
arguments larger than 2^32. Alas, it creates map lookup entries for all
integers<=x, meaning that if you calculate fib(2^32) you perform 2^32
dynamic memory allocations for the map and consume several hundreds of
GB-s of memory. Not so nice.
 
To be useful, the map should probably store only values for selected
points, like each fib(2^n), fib(2^n+1). Again, depends on the usage pattern.
 
> return M[x];
> }
> };
 
This is much better than the first example in terms of memory
allocations, but still suffering from the memory explosion.
 
 
> + A.c*B.c, A.d1*B.c + A.c*B.d2 };
> }
> };
 
This seems interesting and most promising. This looks fast enough to not
need any memoization.
BartC <bc@freeuk.com>: Mar 07 08:34PM

On 06/03/2016 23:06, Juha Nieminen wrote:
>> interface a naïve Fibonacci function with a memoization mapping?
 
> Wouldn't it be easier to just implement it with a loop?
 
> Recursive fibonacci is fancy but inefficient. Just do it iteratively.
 
I think everyone is missing the point.
 
Fibonacci is just an *example*. Quite a good example because memoising
would have a dramatic effect on performance.
 
But it is about memoising a more general function. (I don't know how to
it; I was just curious in seeing the easy C++ solution that was hinted
at in c.l.c.)
 
(I remember when I was using recursive fibonacci as a benchmark. People
came up with better solutions that reduced the number of calls from tens
of millions to a few dozen. Great, except the purpose of the exercise
was to measure how good an implementation was at executing tens of
millions of function calls! The 'better' methods were rubbish at that as
they all executed in 0 milliseconds...)
 
--
Bartc
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 07 10:27PM +0100

On 07.03.2016 21:34, BartC wrote:
 
> I think everyone is missing the point.
 
> Fibonacci is just an *example*. Quite a good example because memoising
> would have a dramatic effect on performance.
 
Yes, memoizing would dramatically reduce performance.
 
This is good to know about.
 
Too many people just blindly apply techniques that they learn from what
they regard as authoritative sources, and end up making things
needlessly complex and inefficient.
 
 
> But it is about memoising a more general function. (I don't know how to
> it; I was just curious in seeing the easy C++ solution that was hinted
> at in c.l.c.)
 
Can go like this:
 
 
<code>
#include <functional>
#include <unordered_map>
#include <utility>
using namespace std;
 
class Memoized
{
private:
function<auto(int)->int> f_;
unordered_map<int, int> values_;
 
Memoized( Memoized const& ) = delete;
auto operator=( Memoized const& ) = delete;
 
public:
auto operator()( int const x )
-> int
{
const auto it = values_.find( x );
if( it != values_.end() )
{
return it->second;
}
const int result = f_( x );
values_.insert( {x, result} );
return result;
}
 
explicit Memoized( function<auto(int)->int> f ): f_( move( f ) ) {}
};
 
auto fib( int const x )
{
static Memoized m( [&]( int x ) -> int
{
fprintf( stderr, "fib(%d) called.\n", x );
return (x == 0? 0 : x == 1? 1 : m( x-1 ) + m( x-2 ));
} );
 
return m( x );
}
 
#include <stdio.h>
auto main() -> int
{
for( int x = 0; x < 10; ++x )
{
printf( "%d -> %d\n", x, fib( x ) );
}
}
</code>
 
 
> was to measure how good an implementation was at executing tens of
> millions of function calls! The 'better' methods were rubbish at that as
> they all executed in 0 milliseconds...)
 
For typical small range of arguments fib can be calculated directly.
 
There no need for "a few dozen" [recursive] calls: it's just one call,
that's it.
 
Above that argument range, say 64-bit, memoization could help if it
didn't use up zillions times more memory than the computer has.
 
 
Cheers & hth.,
 
- Alf
"Öö Tiib" <ootiib@hot.ee>: Mar 06 05:02PM -0800

On Sunday, 6 March 2016 21:10:11 UTC+2, Dombo wrote:
 
> 1. Communication; make sure everyone in the team understands the design
> and understands what should go where and the rationale behind your
> design decisions.
 
Lot of meetings and workshops and documentation about design
are not so much better than inconvenience of misuse.
 
> understand that business logic should not go into the UI code, or lack
> the discipline to keep them separate, fire them. They are gonna cause
> problems in other areas as well so you are better of without them.
 
Staffing is important anyway but too much focus on fear and horror can't
be better than easily observable inconvenience of misuse.
 
 
> 3. Code reviews; make sure that there is more than one person that has
> seen the code before it is committed.
 
That is so either way. It is easier to spot diffusion of responsibilities
during review when it was inconvenient and inelegant to write that.
 
> scope. This makes it obvious were you are in the code and when you are
> crossing boundaries without having to write error-prone/no-added-value
> glue code.
 
That is so either way but I prefer different namespace by module.
For me quality of the interfacing code between modules adds lot of
value since different modules may be made by different teams and so
the integration is typically expensive step. That "no-added-value
glue code" is on what it depends how fast the issues are sorted out
and blamed correctly. Keeping the interface clear and narrow makes
it harder to diffuse responsibilities to other side of it.
 
The layer where data from user interface is converted into application
logic data is precisely where "dirty" data becomes "clean" data. Dirty
data from UI is something about that program has to validate carefully
and reject it nicely when invalid because it is produced by clueless,
clumsy and smug humans. However same may happen with whatever other
module (that may be also produced by clueless, clumsy and smug humans).
 
> communication solutions that alleviate this), but there are other
> reasons why you want to have the UI in a separate process, such as
> reducing the impact of a bug in the UI code.
 
Yes but there we have inter-process communication layer that is
inconvenience of transferring the responsibilities by design and does not
interface smoothly with application layer code.
 
> Python libraries often smoothly work together. Of all the programming
> language I have dealt with the last 20 years (more than I care to
> remember) C++ is the worst offender in this area.
 
Experiences differ. For me worst code that I have ever had to deal with
was a commercial setup tool for specific hardware written in C#. It was
close to worst offender in several areas including lack of consistency of
style whatsoever.
legalize+jeeves@mail.xmission.com (Richard): Mar 07 04:48PM

[Please do not mail me a copy of your followup]
 
Dombo <dombo@disposable.invalid> spake the secret code
>Python libraries often smoothly work together. Of all the programming
>language I have dealt with the last 20 years (more than I care to
>remember) C++ is the worst offender in this area.
 
+1
 
Sometimes the style differences border on the silly. I once had an
engineer insist that "char* p" was legible but "char *p" was illegible.
 
If the moving of a single space character prevents you from reading
code, you have no business being a programmer.
 
My position was that my fingers like to type "char *p" and that our
team should be able to handle either style without difficulty. In
other words, I was reciting "0. Don't sweat the small stuff" from "C++
Coding Standards" by Herb Sutter and Andrei Alexandrescu
<http://amzn.to/1QBURJz>. Apparently obsessing about exceedingly
minor variations in whitespace is what makes code legible. LOL.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
legalize+jeeves@mail.xmission.com (Richard): Mar 07 05:03PM

[Please do not mail me a copy of your followup]
 
Dombo <dombo@disposable.invalid> spake the secret code
>as UI toolkits are concerned, there are god know how many C++ UI
>libraries out there. Qt being arguably the best one if you can live with
>the bloat, but still far from ideal as far as I'm concerned.
 
I disagree that there is no defacto standard. There are two prominent
ones: Qt and wxWidgets. MFC is there as well, but not being cross
platform it never achieved industry wide defacto status. Perhaps
defacto on Windows, though I prefer WTL for Windows only UI
programming.
 
>added those to the language for reason you know) but instead rely on on
>their own kludges to implement features C++ compliers didn't have back
>in the nineties.
 
As someone that works on a Qt application every day and a wxWidgets
application part-time, I disagree. Yes, those things are there if
you want to use them, but nothing is forcing you to use them. I know
in the case of Qt their API is becoming more compatible with STL style
usage in every release.
 
>Another being that C++ UI libraries tend to have their
>own types for string and containers.
 
So does LLVM and clang. Are you going to throw them under the bus as
well for this? std::string is a decent class, but if you have
specific string needs that don't match the semantics of std::string,
there is nothing inherently "bad" about making your own string class.
Similarly for containers.
 
>code (which is error prone and doesn't add value) unless the library
>does every you will ever need, which is probably the reason why Qt
>attempts to provide everything but the kitchen sink.
 
Qt is like emacs. It has a tendency to want to become the only way
you interact with your computer :-).
 
I think some of this is historical evolution of the API and once it
has a certain momentum, people are loathe to give that up in favor of
something else that (as you say) does exactly the same thing. The
biggest downside of all of that is the maintenance surface for the Qt
developers, but they seem to get funding for it.
 
 
>Strawman argument. I'm not arguing for having a C++ UI library in the
>standard. I'm arguing for a UI library that smoothly interfaces with the
>types provided by the standard library.
 
Well, that is what *you* are arguing for, but it wasn't the statement
that started this whole thread. Please re-examine the subject line of
this thread. The original poster linked to a blog post listing all
the stuff proposed for the C++17 standard so far and lamented that the
standard didn't have a GUI library. *That* is what I'm responding to.
 
>> already have defacto standards that are serving the need just fine.
 
>Notice the words "defacto" and "standards" . Now think about that for a
>moment (hint: the latter word is plural).
 
Yeah, there are 2, maybe 3 if you count MFC. Nothing else has enough
brain share or deployed market share to even count as anything close
to a defacto standard.
 
>> and that was done straight on top of Xlib, which was a C API.
>> <http://www.cs.tufts.edu/~nr/cs257/archive/mark-linton/interviews.pdf>
 
>Again strawman argument.
 
No, not a straw man argument, because I am stating this as a hypothetical
reason for why I would understand the clamor. I know what a straw man
argument is and this isn't one. If anything your response is a straw
man argument, LOL.
 
>No one is claiming there are no UI toolkits for
>C++,
 
I never said that they were claiming this. This is where you create
your own straw man argument in response to my explicitly hypothetical
statement.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Mar 07 05:51PM

> Please don't swear here.
 
'This video may contain sexual swearwords, I'm afraid. There are 28
'fucks'. Including that one 29. Ah, fuck it, make it 30.' -- Paul Calf
 
https://www.youtube.com/watch?v=42UCpOzTbNU
 
/Flibble
Juha Nieminen <nospam@thanks.invalid>: Mar 07 09:13AM

> The usual route to tears is to accidentally call a virtual function in a
> constructor.
 
Don't call virtual functions in constructors?
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 07 10:55AM +0100

On 07.03.2016 10:13, Juha Nieminen wrote:
>> The usual route to tears is to accidentally call a virtual function in a
>> constructor.
 
> Don't call virtual functions in constructors?
 
Worth noting that as opposed to Java and C#, in C++ it's safe to call
virtual functions in constructors, in particular calling them indirectly
via base class functions.
 
In Java and C# a virtual method call from a constructor can easily end
up being processed in derived class code, where the necessary
initialization of things that code depends on, has not yet been done.
 
This common error – perhaps the most common cause of bugs in Java –
simply can't happen with calls of virtual functions from a class T
constructor in C++, because in C++ the dynamic type of the object is T.
 
• • •
 
The "don't call virtuals" advice, which is not uncommon, is therefore
misplaced for C++.
 
• • •
 
It's IMHO about the same as using all uppercase names for constants, an
uncritical adoption of an originally meaningful convention in a new
setting where it's not appropriate, and even has negative utility.
 
This also explains the not uncommon argument for the "don't call
virtuals" advice, namely, that one allegedly don't get the effect one
would expect.
 
For only by being ignorant of the C++ rules could one expect something
else than the effect actually delivered, e.g. expecting Java behavior.
 
 
Cheers!,
 
- Alf
scott@slp53.sl.home (Scott Lurndal): Mar 07 02:01PM

>> no different from normal virtual functions. The only difference
>> between them happens at compile time. At runtime there's no difference.)
 
>Calling a pure virtual functions usually ends in tears...
 
The compiler generates calls to __cxa_pure_virtual (normally provided
by crt0 or libc) in the vtable slots for any non-overridden pure-virtual
functions. Can't link without it.
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: