Thursday, November 1, 2018

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

"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 01 05:58AM +0100

On 31.10.2018 21:16, Richard wrote:
 
>> for( int i = 2, n = cards.size(); i < n; ++i )
 
>> ... both avoids warnings and guarantees performance.
 
> Is the performance claim really legitimate?
 
It guarantees a single call of the `size` function. The compiler might
be able to do that on its own, or not. There's no guarantee of
optimization of the original loop, because it depends on whether the
compiler is smart enough to see that no operation modifies the vector.
 
 
> Is there any compiler that isn't going to lift this loop
> invariant out of the loop for you when optimizations are turned on?
 
Don't know, sorry.
 
 
> I find doing this just makes the code less clear
 
I seldom find naming to make code less clear, provided the names are
reasonably descriptive. On the contrary, not naming things tends to
create an unclear mess. `n` is self-explanatory to my eyes, YMMV. :)
 
 
> and introduces a
> variable that can be accidentally (or "cleverly") modified when you
> didn't intent for it to be modified.
 
One can make `n` const if it's declared before the loop.
 
Technically one can do that also within the loop, but it's ugly.
 
I coded up some examples:
 
 
#include <stddef.h> // ptrdiff_t
 
template< class Type >
auto dummy_use( const Type& ) -> bool { return true; }
 
#define $with( ... ) if( const auto& _ = __VA_ARGS__; dummy_use( _ ) ||
true )
 
template< class Container >
auto n_items( const Container& c )
-> ptrdiff_t
{ return size( c ); }
 
struct Iter{ const int n; int i; };
 
class Up_to
{
const int my_n;
public:
template< class F >
void perform( const F& f )
{
for( int i = 0; i < my_n; ++i ) { f( i ); }
}
 
Up_to( const int n ): my_n( n ) {}
};
 
 
#include <iostream>
#include <vector>
#include <iterator> // std::size
using namespace std;
 
auto main()
-> int
{
const vector<int> numbers = {1, 2, 3, 4, 5};
 
// Original code, just modified to avoid signed/unsigned warning/bugs.
for( int i = 0; i < n_items( numbers ); ++i )
{
cout << numbers[i] << ' ';
}
cout << endl;
 
// Near idiomatic.
for( int i = 0, n = n_items( numbers ); i < n; ++i )
{
cout << numbers[i] << ' ';
}
cout << endl;
 
// "Safe" version of the above loop. But IMHO it's just silly.
for( int i = 0, n = n_items( numbers ); i < n; ++i )
{
void n(); // The safety, code below can't change `n`.
cout << numbers[i] << ' ';
}
cout << endl;
 
// Safe and conventional details, but "leaks" `n` to rest of scope.
const int n = n_items( numbers );
for( int i = 0; i < n; ++i )
{
cout << numbers[i] << ' ';
}
cout << endl;
 
// Addresses the leakage of a no-purpose name by using "_" as name.
$with( n_items( numbers ) ) for( int i = 0; i < _; ++i )
{
cout << numbers[i] << ' ';
}
cout << endl;
 
// A silly way to have `n` const and all variables local to the loop.
for( Iter L{ int( n_items( numbers ) ) }; L.i < L.n; ++L.i )
{
cout << numbers[L.i] << ' ';
}
cout << endl;
 
// Not so sure if this is silly, over-engineering, or actually useful?
Up_to( n_items( numbers ) ).perform( [&]( const int i )
{
cout << numbers[i] << ' ';
} );
cout << endl;
 
cout << "Finished!" << endl;
}
 
 
Cheers!,
 
- Alf
James Kuyper <jameskuyper@alumni.caltech.edu>: Nov 01 07:39AM -0400

On 11/1/18 00:58, Alf P. Steinbach wrote:
> be able to do that on its own, or not. There's no guarantee of
> optimization of the original loop, because it depends on whether the
> compiler is smart enough to see that no operation modifies the vector.
 
For loops in general (not just this particular code), if the compiler
can't see that no operation modifies the vector, that might be because
the loop contains some code which does modify the vector. If that were
the case, using n rather than cards.size() could have really nasty
consequences.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Nov 01 02:01PM +0100

On 01.11.2018 12:39, James Kuyper wrote:
> the loop contains some code which does modify the vector. If that were
> the case, using n rather than cards.size() could have really nasty
> consequences.
 
You're saying, if the code is incorrect you'd rather give it the best
possible shot of not crashing or producing obviously wrong result?
 
Hm!
 
 
Cheers!,
 
- Alf
jameskuyper@alumni.caltech.edu: Nov 01 07:09AM -0700

On Thursday, November 1, 2018 at 9:01:47 AM UTC-4, Alf P. Steinbach wrote:
> > consequences.
 
> You're saying, if the code is incorrect you'd rather give it the best
> possible shot of not crashing or producing obviously wrong result?
 
No, I was talking about code which uses
 
for(int i=2; i < cards.size(); i++)
 
to control a loop body that can, under some circumstances, cause
cards.size() to change, and which deals correctly with that
possibility. The simplest case is that it might add cards to the
end of the container, but it's entirely feasible for such a loop
to delete cards or insert them anywhere in the container,
possibly requiring that the body of the loop change the value of
i. It's easy for code with such features to be written
incorrectly; it requires careful attention to write such code
correctly. However, the presence of such features does not, in
itself, guarantee that the code is incorrect. And if you change
such code to use for( int i = 2, n = cards.size(); i < n; ++i ),
it will become incorrect.
legalize+jeeves@mail.xmission.com (Richard): Nov 01 04:43PM

[Please do not mail me a copy of your followup]
 
James Kuyper <jameskuyper@alumni.caltech.edu> spake the secret code
>the loop contains some code which does modify the vector. If that were
>the case, using n rather than cards.size() could have really nasty
>consequences.
 
This question seems to be an obvious situation to use compiler
explorer.
 
When I compile with no optimizations, I see calls to size().
 
When I compile with -O1 or -O2 I don't see calls to size(), I see a
simple increment and compare.
 
WHen I compile with -O3, it starts using SSE vectorization on the loop
and things get "longer".
 
<https://godbolt.org/z/PkCT2L>
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Terminals Wiki <http://terminals-wiki.org>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>
Marcel Mueller <news.5.maazl@spamgourmet.org>: Nov 01 07:52PM +0100

Am 31.10.2018 um 15:34 schrieb Paul:
> Below is my code for determining if a given sequence of distinct
> integers has a decreasing subsequence of length 3.
> Is there a standard range-based approach for writing for(int i = 2; i < x.size(); ++ i)
 
Some containers provide virtual slices that refer to subsections of the
original container. But the standard containers AFAIK do never.
 
However, I would rather use a more elegant algorithm:
 
#include <algorithm>
#include <numeric>
#include <vector>
#include <iostream>
 
int main()
{
std::vector<int> cards { 5,9,2,3,5,4,8,3,2,4,5,6,2,9 };
std::adjacent_difference(cards.begin(), cards.end(), cards.begin(),
std::less<int>{});
std::cout << (cards.end() != std::adjacent_find(cards.begin()+1,
cards.end(), std::logical_and<int>{}));
return 0;
}
 
Unfortunately this algorithm needs a temporary storage since C++ does
not provide stream operations like Java or .NET.
 
 
Marcel
Juha Nieminen <nospam@thanks.invalid>: Nov 01 07:10PM

> You're saying, if the code is incorrect you'd rather give it the best
> possible shot of not crashing or producing obviously wrong result?
 
What he is saying is that if the code is modified so that it changes
the size of the vector, it will start misbehaving.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Nov 01 07:45PM

On Wed, 2018-10-31, Paul wrote:
> distinct.
 
> bool isRiffleShuffle(const std::vector<int>& cards)
> {
 
One observation: since the problem is about a deck of cards rather
than a vector<int>, when you get the latter working you could
generalize it to:
 
template<class Card>
bool isRiffleShuffle(const std::vector<Card>&);
 
and then to:
 
template<class ForwardIterator>
bool isRiffleShuffle(ForwardIterator begin,
ForwardIterator end);
 
Perhaps I'm contradicting myself here, since earlier I argued against
generalizing too early. But in a real application, I'd hate to
convert my deck of cards to ints to be able to tell if they're
decently shuffled.
 
/Jorgen
 
--
// jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
jameskuyper@alumni.caltech.edu: Nov 01 01:24PM -0700

On Thursday, November 1, 2018 at 3:11:00 PM UTC-4, Juha Nieminen wrote:
> > possible shot of not crashing or producing obviously wrong result?
 
> What he is saying is that if the code is modified so that it changes
> the size of the vector, it will start misbehaving.
 
No, that's not what I'm saying.
 
First, let me make it clear that the code I'm talking about is NOT the
particular function that Paul was talking about in his original message.
It's hypothetical code containing a similarly controlled loop that is
correctly written to perform an unspecified task, one that requires
either adding items to or removing items from the vector, possibly both.
 
What I'm saying is that changing the loop controls in such code to use
i < n rather than i < cards.size() could cause it to start misbehaving.
It might either terminate before processing all elements of the vector,
or attempt to access a non-existent element of the vector.
"Öö Tiib" <ootiib@hot.ee>: Nov 01 02:10PM -0700

> i < n rather than i < cards.size() could cause it to start misbehaving.
> It might either terminate before processing all elements of the vector,
> or attempt to access a non-existent element of the vector.
 
That is correct both ways. Also code that did work correctly with
"for (int i = 2, n = cards.size(); i < n; ++i)" could become silently
incorrect after changing to "for (int i = 2; i < cards.size(); i++)".
Hypothetical body of hypothetical loop is such a blurred thing.
bitrex <user@example.net>: Oct 24 09:20PM -0400

On 10/24/2018 03:03 PM, Lynn McGuire wrote:
> "Why does the C programming language refuse to die?"
 
C is "The Rooster." No, no, he ain't gonna die.
 
<https://www.youtube.com/watch?v=ZUqBglpHTO0>
 
 
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Oct 24 09:54PM +0200

On 24.10.2018 21:03, Lynn McGuire wrote:
 
> "Applications that stand the test of time"
 
> "C: the backbone of our operating systems"
 
> "What does the future holds for C?"
 
Disclaimer: I haven't read that article.
 
It's an interesting (to me) question whether C++ can be evolved so that
all the intrusive runtime support relative to C, which stands in the way
of using C++ in some contexts, is removed.
 
The most offensive feature in that respect is IMHO exception handling,
but there Herb Sutter has proposed a much more elegant scheme than the
current, with minimal/no runtime support. More like Eiffel. Nom nom.
 
Then we have thread support. The current C++11 stuff can probably be
made optional, like a library. After all it started out as a separate
library, in Boost. But the upcoming transactional memory stuff, with
dedicated keywords, sounds much more entangled with the core language,
difficult to remove. And is designed from the start as an integrated
part of the language: no history (that I'm aware of) as a separate
library. So, no guidance and experience in how to factor that out. :(
 
Dynamic memory management may have some default C++ specific runtime
support, e.g. for all I know some implementation might have an efficient
small objects sub-allocator involved, but one can always just define
`::operator new` etc. to use the C `malloc`-family facilities.
 
I think that's it, roughly (am I very wrong there?), and if so, then the
main thing that stands in the way of using C++ where C is now used, is
the upcoming transactional memory stuff. Let's hope it's not adopted.
But if history serves as guidance, it will be. :( :( :(
 
 
Cheers!,
 
- Alf
bitrex <user@example.net>: Oct 24 04:30PM -0400

On 10/24/2018 03:54 PM, Alf P. Steinbach wrote:
> But if history serves as guidance, it will be. :( :( :(
 
> Cheers!,
 
> - Alf
 
I get the impression that C is still successful is because what the
people who made it set out to make was a programming language. the later
"Better Cs" were made by people who set out to make a programming
language....because they hate C! ugh! C's the worst! Arrrghhh....
 
It shows
bitrex <user@example.net>: Oct 24 04:43PM -0400

On 10/24/2018 04:25 PM, David Brown wrote:
 
> -fno-rtti flags in small embedded systems.  Part of it is FUD and
> conservatism - a lot of embedded code is written in C90, rather than C99
> or C11, and C++ is still viewed as "new and complicated".
 
it is misplaced conservatism IMO. I see few advantages to using C on
embedded platforms in year of our Lord 2018, even platforms like the
MSP430. C++ makes the lack of intrinsic dynamic memory management on
devices with small amounts of RAM _easier_ to live with, not less so
Ian Collins <ian-news@hotmail.com>: Oct 25 09:13AM +1300

On 25/10/18 08:54, Alf P. Steinbach wrote:
 
> The most offensive feature in that respect is IMHO exception handling,
> but there Herb Sutter has proposed a much more elegant scheme than the
> current, with minimal/no runtime support. More like Eiffel. Nom nom.
 
Yes, I have used C++ without exceptions and RTTI in places (drivers)
which are usually the exclusive domain of C. You can also statically
link the C++ run-time, but that's a bit of an overkill.
 
--
Ian.
scott@slp53.sl.home (Scott Lurndal): Oct 24 08:23PM


>It's an interesting (to me) question whether C++ can be evolved so that
>all the intrusive runtime support relative to C, which stands in the way
>of using C++ in some contexts, is removed.
 
Sans Exceptions, Sans RTTI and sans STL, we have built two operating
systems and a large-scale hypervisor using C++ (consider it the C++ 2.1
subset) at various large companies (Unisys, SGI, 3Leaf Systems).
 
All dynamically allocated data structures override operator new/delete
and use pool allocators.
 
All we needed to add was this:
 
/*
* This is called by setup64.S to call the constructors of global objects,
* before it calls dvmm_bsp_start().
*
* GNU LD lays out the __CTOR_LIST__ as an array of function pointers. The
* first element of the array (index == 0) contains an integer which
* represents the value derived from subtracting two from the actual number
* of entries in the table. Thus the content of the first element is
* one less than the index of the last entry in the table.
*
* Call in reverse order XXX - why? Check crt0.o for canonical behavior
*/
extern "C" void
__call_constructors()
{
size_t count = *(size_t *)__CTOR_LIST__;
 
for(count++; count; --count) {
__CTOR_LIST__[count]();
}
}
 
/*
* G++'s generated code calls this if a pure virtual member is ever called.
*/
extern "C" void
__cxa_pure_virtual()
{
panic("pure virtual function called\n");
}
 
/*
* This is needed even though we don't ever use the delete operator because
* G++ generates an extra (unused) virtual destructor that calls it.
*/
void
operator delete(void *)
{
panic("operator delete(void*) called\n");
}
 
/*
* Catch unintended calls to new.
*/
void*
operator new(size_t)
{
panic("operator new(void*) called\n");
}
 
 
/*
* G++ generates code for shared library support, even though it isn't
* relevant (or called). That code looks for this symbol.
*/
void *__dso_handle;
 
/*
* Global object constructors call this to register their corresponding
* destructor. We just ignore it; we never call global object destructors
* because we never exit.
*/
extern "C" int
__cxa_atexit(void (*f)(void *), void *p, void *d)
{
return 0;
}
Lynn McGuire <lynnmcguire5@gmail.com>: Oct 24 02:03PM -0500

"Why does the C programming language refuse to die?"

https://hub.packtpub.com/why-does-the-c-programming-language-refuse-to-die/
 
"Portability leads to true ubiquity"
 
"Programmer-driven memory management"
 
"Structure is all I got"
 
"Applications that stand the test of time"
 
"C: the backbone of our operating systems"
 
"What does the future holds for C?"
 
Lynn
David Brown <david.brown@hesbynett.no>: Oct 25 10:00AM +0200

On 24/10/18 22:43, bitrex wrote:
>> conservatism - a lot of embedded code is written in C90, rather than
>> C99 or C11, and C++ is still viewed as "new and complicated".
 
> it is misplaced conservatism IMO.
 
Oh yes, I agree on that.
 
There is also entirely reasonable conservatism - when your current
project is build by starting with the previous project and modifying it,
and so on back through the history for the last 20 years, it is hard to
make big changes to the fundamentals like the language. Then you have
things like developer experience - if most of your developers are not up
to speed on modern C++, it makes sense to stick to C for your project.
That of course means that for the next project, they are not up to speed
on modern C++ and it makes sense to stick to C...
 
A key sticking point that I see is major RTOS's and assorted libraries
like network stacks. These are usually written in C90, often in a
terrible type-unsafe style (lots of void* pointers) with their own
personal sized integer types, their own design flaws that require
special compiler flags or optimisation restrictions on modern compilers,
etc. But they are tried and tested, certified and field-proven - and
that is hugely important.
 
> embedded platforms in year of our Lord 2018, even platforms like the
> MSP430. C++ makes the lack of intrinsic dynamic memory management on
> devices with small amounts of RAM _easier_ to live with, not less so
 
Small platforms like the msp430 /do/ have dynamic memory support in
their standard libraries - you have malloc() and free() just like
anywhere else. However, it is unlikely that it makes sense to use it -
you have risks of heap fragmentation, unpredictable timings, and in most
dedicated embedded systems, a memory allocation failure is a critical
failure of the system. Dynamic memory is hugely more complex to analyse
to be sure the system is correct - so static allocation is the norm.
(Alternatives include a very simple malloc implementation and no free,
or dedicated pools for particular uses.)
 
This applies to C and C++ equally. C++ RAII can make it a lot easier to
track allocations and avoid memory leaks than manual dynamic memory
handling in C, but it does not make any difference to the reasons why
small embedded systems usually avoid dynamic memory.
 
 
But perhaps the biggest reason for choosing C over C++ in embedded
systems, especially small systems (rather than embedded Linux or
platforms with MB of memory) is about people. Anyone who has experience
of working with small embedded systems will be experienced with C,
hopefully also assembly, and perhaps also with hardware and electronics.
If you try to get hold of new programmers with good C++ experience,
however, they are likely to come from the world of "big" programming -
multi-GHz, multi-GB, multi-core systems. Usually they simply do not
understand what is important in small systems. They want to use boost,
and unordered_map, and multiple virtual inheritance, and they wonder why
their 30 MHz, 64 KB target can't cope. (I've seen similar things with C
programmers too, but to a lesser extent.)
BGB <cr88192@hotmail.com>: Oct 25 02:42PM -0500

On 10/24/2018 3:30 PM, bitrex wrote:
> "Better Cs" were made by people who set out to make a programming
> language....because they hate C! ugh! C's the worst! Arrrghhh....
 
> It shows
 
Or, from the POV of a language designer who actually likes C:
Makes a language, could try to pass it off as a "C replacement";
Doesn't really bother, C still does C things pretty well (and there are
still non-zero cost of using my language in places where C works).
 
I have also written a C compiler (and a more experimental limited subset
of C++), so these are also options (for use-cases where I am using a
custom compiler).
 
 
A downside with doing a "C replacement" is that many of the "flaws" of C
will still exist if one makes a language which can address the same
use-cases:
If one tries to side-step them (by omitting things), then the language
is painful to use;
If one tries to provide alternatives that do similar, but are
"safer"/..., then they come with overhead;
One can't do a "simple" language and aim for this use-case, as by the
time it is "actually usable", then complexity is already on-par with C;
...
 
While dynamic / "high level" languages can address some use-cases pretty
well, in the context of a "C alternative" they are generally unusable.
Similar generally goes for languages with more wildly different language
designs, ...
 
 
Many people add features which require runtime support, such as garbage
collection, which makes it unsuitable for many use-cases (ex: hard
real-time and smaller microcontrollers); and even on big, fast,
soft-real-time uses (ex: typical desktop PC) they are not ideal (the GC
still almost invariably sucks in one area or another).
 
Things like exceptions are "use with caution"; need to keep ABI cost
minimal. The best scheme I am (currently) aware of is doing it similar
to the Win64 ABI (using using instruction ranges and using the epilog
sequence for unwinding). There is still a cost for storing a table with
per-function pointers (ex: 8 or 16B or so per-function).
 
 
Things like bounds-checked arrays are doable, but typically add the cost
of requiring the use of "fat pointers" or similar (either passed in GPRs
or indirectly via reference or the usual "pass struct by value"
mechanism for the ABI, *).
 
I have used this in my own language (which uses an arrays partway
between the C and Java/C# styles), but it still carries a bit of
overhead vs C-style raw pointers.
 
*: Mostly leaning against going into "pass struct by value" mechanisms
here (this varies a fair bit between architectures and ABIs).
 
 
By the time a type-system is capable enough to do "all the usual C
stuff", it is already about as complicated as what is needed for the C
typesystem (or one pays in other ways).
 
Though, one can still simplify things partly vs the surface-level
language (this also applies to C), and divide the types into major types
and sub-types.
 
For Example: ILFDAX
* I: 32-bit int and sub-types.
* L: 64-bit long and sub-types.
* F: 32-bit float and sub-types.
* D: 64-bit double and sub-types.
* A: pointers / arrays / "struct by ref" / ...
* X: 128-bit types (int128, float128, vec4f, small structs, ...).
 
So, for example, everything which can fit into an 'int' or 'unsigned
int' could fit into 'I'; everything which is internally treated as a
64-bit integer type goes into 'L', ...
 
This is very similar to the model used internally by Java, but can be
made to accommodate C.
 
The main remaining "hair" area is that C treats "int" and "unsigned int"
a bit differently in some areas, which may require dealing specially
with unsigned cases in some cases. But, likewise, this is true for
pretty much any language which has unsigned integer types.
 
 
OO / object-system, generally needed "de-facto" for a language to be
taken seriously, but even in the simplest cases add complexity over "not
having an object system".
 
Vs the C++ object system, it is possible to simplify things somewhat
though. Most obvious: Doing like Java and C# and dropping Multiple
Inheritance.
 
 
Similarly, one can do like C# and split 'struct' and 'class' into two
functionally distinct entities. This can reduce some implementation hair
vs trying to make both exist.
 
My case, I still have some complexity (of class-like structs) mostly as
it is still needed to support the C++ subset (though my subset did drop
MI). ( FWIW: Both my custom language and the C++ subset share the same
underlying compiler in this case; and aren't too far off from being
effectively re-skins of the other, *. Though another separate VM based
implementation of this language also exists. )
 
Similarly, in my case it is also possible to use the "natively compiled"
version in VM style use cases mostly by compiling to a RISC style ISA
and then using partial emulation (such an ISA can still be useful while
also still being relatively simple; and can protect the host's memory
via an address-space sandbox, or possibly with selective use of a
"shared memory" mechanism, ...).
 
*: Partly as a consequence, many things in one can be expressed in the
other "just with slightly different syntax", and while not quite as
copy/paste compatible with C as C++ is (due to mine using a more
Java-ish declaration syntax), cross-language interfacing is otherwise
relatively straightforward (same underlying ABI). This doesn't currently
target x86 based systems, but could probably do so if needed.
 
 
All it really leaves is C having (pros/cons) exposed raw pointers, and
some amount of ugly-named extension keywords (which can be remapped via
typedefs or defines).
 
And, my case, I also have some features from my other language exposed
in C land via similarly ugly extensions, but generally not used much as
reliance on language extensions is not good for code portability (apart
from cases where the extension is implemented in a way where a plain C
fallback can be provided).
 
Similarly, between the custom language and a C++ subset, the latter
(also) has the advantage that code written in it will still work in a
normal C++ compiler (and still has the drawback of it being C++ rather
than C).
 
 
Combined, a lot of this doesn't really make for a particularly strong
case for trying to replace C.
David Brown <david.brown@hesbynett.no>: Oct 24 10:25PM +0200

On 24/10/2018 21:54, Alf P. Steinbach wrote:
> difficult to remove. And is designed from the start as an integrated
> part of the language: no history (that I'm aware of) as a separate
> library. So, no guidance and experience in how to factor that out. :(
 
There is no problem with features in the core language as long as they
don't cost if they aren't used.
 
C++11 threads and atomics, for example, are not a problem - if you don't
use these, they cause almost no overhead because the relevant functions
from libraries are not linked in. The same applies to C11 threads and
atomics. (There is one PITA - thread-safe static initialisation. It is
a cost that is, for the most part, completely unnecessary. There should
be some way to define variables that are static, local to a function,
but initialised pre-main just like namespace scope statics.)
 
I expect the same will apply to transactional memory stuff - if you
don't use any of these features in your code, the library overhead will
not need to be linked in.
 
Exceptions are a different matter. The way exceptions work in C++ today
is that they are enabled and active by default, in all functions. You
pay for them everywhere - you have the stack unwind tables that can be a
very significant code cost in embedded systems, and you have the (small
but non-zero) optimisation limitations from the requirements of being
able to unwind the stack. RTTI is in the same bag - it costs by default.
 
So as far as I can see, it's fine to have new things in the core
language and support libraries, as long as they don't lead to more
linked library code when they are not used.
 
> main thing that stands in the way of using C++ where C is now used, is
> the upcoming transactional memory stuff. Let's hope it's not adopted.
> But if history serves as guidance, it will be. :( :( :(
 
The new exception system, if implemented, will help a lot. But there
are other reasons why C is more popular than C++ with -fno-exceptions
-fno-rtti flags in small embedded systems. Part of it is FUD and
conservatism - a lot of embedded code is written in C90, rather than C99
or C11, and C++ is still viewed as "new and complicated".
bitrex <user@example.net>: Oct 25 11:56AM -0400

On 10/25/2018 04:00 AM, David Brown wrote:
> track allocations and avoid memory leaks than manual dynamic memory
> handling in C, but it does not make any difference to the reasons why
> small embedded systems usually avoid dynamic memory.
 
I guess the intent I was going for by my comment is that modern C++
allows you to more effectively implement data structures and algorithms
which preferentially use the stack to get their work done, via holding
composite objects by value and judicious use of move constructors and
assignment operators.
 
Yeah at some level you will likely have to hold a resource which is
statically allocated on the heap and not repeatedly allocated and freed
to avoid risk of fragmentation, but you can write everything up the
chain such that it's clear and enforced who the "owner" of that resource
is at any particular time - even if it isn't freed in the lifetime of
the program IMO ownership should still be enforced it shouldn't be a
free-for-all.
 
David Brown <david.brown@hesbynett.no>: Oct 25 10:10AM +0200

> technology needs to be friendly/benign or it will wither away.
> Sometimes executives say dumb things, but in this case Mr. Cook
> is correct.
 
Do you have shares in Duckduckgo or something? This is a C++ group, not
a "please use my favourite search engine" group.
 
And if Cook is arguing for greater privacy of data and less collection
of private data by US companies, he is a howling hypocrite. Apple
collects everything it can get its claws on - just like Microsoft,
Google, Facebook, and similar companies. (But not, of course, your
beloved Duck company.) If he wants laws to reduce this, it is only
because his company is losing compared to the other big ones, and he
wants help from the law to pull them down.
 
All these companies - Duckduckgo included - are there to make /money/.
that is their purpose. Duckduckgo does not minimise tracking and
personal information because it is a "nicer" or more "ethical" company -
it does it because taking that stance gives them a different segment of
the search market, and lets them make money. Apple will use Duckduckgo
for searches if they think that will make them more profits, and will
use Google, Bing, Yahoo, or whatever if they think those will be more
profitable.
 
You make your own choices about which services or companies you want to
use. You can base those choices on reality, or the little fantasy world
you live in. But there is no need to keep advertising them here.
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Oct 25 01:27PM -0700

>>> won't be such an issue.
 
>> Get a load of this cat.
 
> Did you just step out of a 1970s B movie?
 
Fritz the Cat?
boltar@cylonhq.com: Oct 25 10:03AM

On Wed, 24 Oct 2018 15:55:18 -0400
>> from scratch then perhaps move over to web coding where your lack of ability
>> won't be such an issue.
 
>Get a load of this cat.
 
Did you just step out of a 1970s B movie?
Christian Gollwitzer <auriocus@gmx.de>: Oct 24 08:53AM +0200

Am 24.10.18 um 01:06 schrieb Öö Tiib:
> express that but you considered it good idea to cut it in reply:
> "Implementing it separately feels pointless in modern world where
> non-naive implementation of LZW is often quicker than memcpy."
 
Sorry I missed that. I thought you were saying this is a theoretical
concept, while I was trying to say that it is indeed part of one of the
most widely used compression schemes. So I think we agree :)
 
Christian
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: