Sunday, September 30, 2018

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

"Öö Tiib" <ootiib@hot.ee>: Sep 29 06:27PM -0700

> > Have you benchmarked against malloc and free compiled as single-threaded?
 
> I used the latest dlmalloc source (the mother of most if not all
> malloc implementations) which does not have lock enabled by default.
 
That dlmalloc has thread-safety when USE_MALLOC_LOCK is defined and that
must be defined in multi threaded program unless someone wants to use
it narrowly for managing state that fully belongs to single thread
only.
There are no authorities, mothers and fathers in software development
products. Instead lot of people write and rewrite and repair and break
similar algorithms from year to year.
 
 
> An approach is basically have a thread local variables to keep track
> of memory pool including system malloc/free is being used.
> And switch to use specific pool using the flag.
 
But your cookmem does not do that, it is just totally thread-unsafe?
Also its architecture is not designed to carry described thread
local pools. It could be instrumented with locks at best.
 
> process model. I do not want to get into thread vs process
> debate. However, threads are typically lighter weight, and
> lower synchronization costs. Resource managements are also simpler.
 
All we talk about is resource management, particularly memory
management here. Indeed it is simpler with thread-safe allocator.
However with thread-unsafe allocator it will be rather complicated
and error-prone. Someone naively using cookmem in their network service
will possibly open it up to wide array of attack vectors.
 
> it to magically solve the problem. It requires certain architectural
> designs such that memory pool provides the benefits. For typical
> non-server applications, one may never need it.
 
Yes but if global malloc and free are replaced with thread-unsafe
then the tools to control that aspect of architecture are abstracted
away from architect's hands. The fundamental block, the thread-safe
allocator upon what architect can build thread-local pools if needed
is now missing from the landscape.
 
> For a long running server process, how to avoid memory leak,
> fragmentation, etc are challenging issues. CookMem is intended
> to be a part of solutions, rather than the solution by itself.
 
I did not ask about other possible programming problems. I was
particularly interested in under what scenario you consider
your thread-unsafe allocator to be viable as part of solution.
We have plenty of other issues to solve, but those are orthogonal
to thread-safety of allocator.
superduperhengyuan@gmail.com: Sep 29 07:10PM -0700

To Öö Tiib
 
CookMem itself does not provide thread safety at all. In fact, I clearly stated that it does not have locking. Yet, this is not an important feature for memory context like CookMem for the reasons below.
 
Instead of using a single malloc that always locks during allocation / deallocation, it is in fact more efficient that each thread has its own lock-free memory context. If you have specific data needs to be shared as shared / global memory, do the locking yourself in the shared / global memory context. After all, if the usage pattern is that most memory allocated in the local thread are not shared, why pay the extra locking cost?
 
In the end, CookMem is just a tool. It is up to you to find if it is useful.
 
Heng Yuan
"Öö Tiib" <ootiib@hot.ee>: Sep 29 07:54PM -0700

> clearly stated that it does not have locking. Yet, this is not an
> important feature for memory context like CookMem for the reasons
> below.
 
Ok.
 
> yourself in the shared / global memory context. After all, if the
> usage pattern is that most memory allocated in the local thread are
> not shared, why pay the extra locking cost?
 
But does cookmem provide that alternative lock-free thread-specific
memory context? My cursory skimming through it made impression that
no, that it would be tricky to enhance it with the feature. Sure, I
may be wrong, but then can you explain, how?
 
> In the end, CookMem is just a tool. It is up to you to find if it is useful.
 
That is certainly true and so I wanted to understand in what scenarios
you consider cookmem to be actually viable as tool.
superduperhengyuan@gmail.com: Sep 29 09:21PM -0700

On Saturday, September 29, 2018 at 7:55:04 PM UTC-7, Öö Tiib wrote:
> memory context? My cursory skimming through it made impression that
> no, that it would be tricky to enhance it with the feature. Sure, I
> may be wrong, but then can you explain, how?
 
You can make it thread-specific. I do not have any code related to this area since it is not limited to this use.
 
You can also take a look at.
 
https://en.wikipedia.org/wiki/Region-based_memory_management
 
CookMem is basically a memory context implemented using algorithms of dlmalloc.
 
Heng Yuan
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Sep 29 10:02PM -0700

> CookMem is a a memory context / allocator written in C++11 that can be easily and quickly cleaned up by freeing the segments,
 
> rather than doing individual frees.
 
Like a region allocator?
 
 
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Sep 29 10:12PM -0700

>> other thread? Having such complications would make it error-prone,
>> but still useful as performance optimization.
 
> An approach is basically have a thread local variables to keep track of memory pool including system malloc/free is being used. And switch to use specific pool using the flag.
[...]
 
You want to have the "fast path" be thread local, completely isolated
and free of synchronization, implicit or explicit. The "really slow
path" can try to allocate more memory, or fail. I have a lot of
experience wrt creating these types of allocators. Also, take a look at
the allocator in TBB.
 
https://www.threadingbuildingblocks.org/tutorial-intel-tbb-scalable-memory-allocator
 
Also, how does your algorithm deal with false sharing? This can tear
things apart at the seams wrt performance...
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Sep 29 10:23PM -0700


> You can also take a look at.
 
> https://en.wikipedia.org/wiki/Region-based_memory_management
 
> CookMem is basically a memory context implemented using algorithms of dlmalloc.
 
There is a tricky way to create an allocator that uses nothing but
memory on a threads stack. It even allows for a memory M allocated by
thread A to be freed by thread B. It is sync-free in the fast path, and
lock-free in the slow path. I was experimenting around with a tricky way
to get another path that can be wait-free. So the levels went something
like:
______________________
(completely thread local)
fast-path = sync-free
 
(can communicate with another thread)
slow-path = wait-free
snail-path = lock-free
______________________
 
This was a long time ago, 10 years at least.
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Sep 30 01:08PM -0700

On 9/29/2018 10:02 PM, Chris M. Thomasson wrote:
>> easily and quickly cleaned up by freeing the segments,
 
>> rather than doing individual frees.
 
> Like a region allocator?
 
Perhaps, something like Reaps might help you out:
 
https://people.cs.umass.edu/~emery/pubs/berger-oopsla2002.pdf
 
The key phrase: "rather than doing individual frees"
 
makes me think of region-like allocation.
 
 
James Kuyper <jameskuyper@alumni.caltech.edu>: Sep 30 09:22AM -0400

On 09/29/2018 03:01 AM, Ralf Goertz wrote:
> Am Fri, 28 Sep 2018 09:28:30 -0700 (PDT)
> schrieb Öö Tiib <ootiib@hot.ee>:
...
 
> Thanks, James. But what difference does that make? If the short operands
> get promoted to int and the result gets demoted to short, can that
> really be different from doing it directly? The program
 
Yes, it can. First of all, expressions that would overflow when using
the smaller type can be perfectly safe wehn evaluated using the larger
type. Overflow is undefined behavior, which is generally a bad thing,
but it is quite common on modern machines for signed integer types to
use 2's complement notation, and for overflow to be handled accordingly
without any other negative consequence, which means that expressions
which would overflow in the smaller type might produce exactly the same
result as if that type had been used. However, C still allows
implementations to use sign-magnitude and one's complement notation, for
which that equivalence would not hold.
 
Non 2's complement signed types are rare. However, being aware of the
integer promotions is important for understanding the behavior of other
expressions which are more problematic. Unsigned types with a maximum
representable value that is <= INT_MAX promote to int. As a result,
expressions that you might otherwise have expected to be resolved using
unsigned math may end up using signed math instead.
Tim Rentsch <txr@alumni.caltech.edu>: Sep 30 10:23AM -0700


> A char type is an integral type. [...] char can be signed or
> unsigned but it is also a distinct type from signed char or
> unsigned char. It has no special status beyond that.
 
Actually it does have one: it is one of only three types (the
other two being unsigned char and std::byte) that are exempt from
type access rules given in section 6.10.
 
(It's interesting that signed char is not on that list, which
in C it is.)
Tim Rentsch <txr@alumni.caltech.edu>: Sep 30 10:58AM -0700

>> definition of the italicized term.)
 
> [...] Why can't [u]int8_t be separate types and not typedef'ed to
> [un]signed char [...]?
 
They can be. They don't have to be, but they can be. (I should
add, certainly in C, and I am pretty sure for C++.)
 
> What is gained by these typedef?
 
They make things easy for lazy implementors.
 
To be fair I should add that allowing the [u]intN_t types to be
typedefs gives a degree of freedom to implementations, and which
could be passed on to developers with a compiler option, if that
were thought to be important. Personally I would favor having
such an option, although it isn't one I would put high on a
priority list.
 
> [Assuming CHAR_BIT == 8] I can't think of any task done with
> [u]int8_t that can't also be done as easily without it.
 
Advantages of unsigned char (the type, not necessarily using that
name) over uint8_t:
 
(1) It's guaranteed to exist;
 
(2) It's guaranteed to allow access to any type of
object; and
 
(3) No #include is needed to use it.
 
Advantages of signed char (the type, not necessarily using that
name) over int8_t:
 
(1) It's guaranteed to exist;
 
(2) (In C, not C++) It's guaranteed to allow access to any
type of object; and
 
(3) No #include is needed to use it.
 
The minimum value for signed char may be -127, whereas the
minimum value for int8_t (if it exists) must be -128. But if
that property is desired, it can be checked staticly using the
value of SCHAR_MIN, and if int8_t exists then signed char will
also have a minimum value of -128.
 
Considering the above I see no reason to ever use the [u]int8_t
types, except in cases where it's important to conform to an
existing interface that uses them.
Tim Rentsch <txr@alumni.caltech.edu>: Sep 30 11:11AM -0700

> a byte, then I have to use 16 or 32 bit types. In some cases 8
> bit is enough but there are so many vectors in that set that I get
> into memory trouble when using 16 bit. [...]
 
If you really need an 8-bit integer type, you might consider
making one yourself as a class (or maybe one of the newfangled
enum's, but I haven't used those much). Here is a sketch:
 
#include <iostream>
 
class U8 {
unsigned char v;
public:
U8() : v( 0 ) {}
U8( unsigned uc ) : v( uc ) {}
operator unsigned(){ return v; }
U8 &operator=( unsigned uc ){ v = uc; return *this; }
unsigned value(){ return v; }
};
 
std::istream &
operator >>( std::istream &in, U8 &u8 ){
unsigned u;
in >> u;
u8 = u;
return in;
}
 
int
main(){
U8 u8;
std::cout << "Hello, world\n";
std::cin >> u8;
std::cout << "Value of u8 is " << u8 << "\n";
std::cout << "sizeof u8 = " << sizeof u8 << "\n";
return 0;
}
 
 
Disclaimer: the code compiles and runs, but I'm not sure I've
made good choices about the conversions or really anything else.
The point is it should be possible to define a type with the
properties that you want, provided of course the compiler being
used is good enough to make the class be a single byte in size.
Richard Damon <Richard@Damon-Family.org>: Sep 30 02:26PM -0400

On 9/30/18 1:58 PM, Tim Rentsch wrote:
 
> Considering the above I see no reason to ever use the [u]int8_t
> types, except in cases where it's important to conform to an
> existing interface that uses them.
 
The main reason I use uint8_t/int8_t is stylistic to indicate that what
it holds in treated as a small number and not something 'character'
related. It also signals that I may be making an implicit assumption
that the machine is 'normal' (twos complement, 8 bit byte) rather than
adding a static test of preprocessor symbols. To me, char is only used
to actually hold text, and unsigned char for text that all values need
to be positive (for text processing function calls) or accessing 'raw'
memory.
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 30 08:00PM +0100

On Sun, 30 Sep 2018 10:23:24 -0700
> type access rules given in section 6.10.
 
> (It's interesting that signed char is not on that list, which
> in C it is.)
 
OK, well if one of three counts as having special status, then another
related one is assigning or otherwise evaluating integrals, pointers and
some other objects which have not been initialized and so have
indeterminate value. In most cases this is undefined behaviour, but in
the case of char, unsigned char and std::byte it just gives you another
indeterminate value.
 
int i; // indeterminate value
int j = i; // undefined behaviour
 
char c; // indeterminate value
char d = c; // indeterminate value
 
There may be other special cases of that kind. But these all relate to
the fact that these types may be used for low level byte access in C++
rather than that they are "characters".
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 30 08:03PM +0100

On Sun, 30 Sep 2018 20:00:52 +0100
 
> There may be other special cases of that kind. But these all relate to
> the fact that these types may be used for low level byte access in C++
> rather than that they are "characters".
 
One correction - this only works with char (as opposed to unsigned char
or std::byte) if, in the implementation in question, char is unsigned.
Tim Rentsch <txr@alumni.caltech.edu>: Sep 30 10:05AM -0700


> I presume APL didn't try to define an operator precedence because
> it has SO many operators no one could agree on an order, let alone
> attempt to remember it.
 
My understanding is APL uses right-to-left grouping for all
operators because its inventor, Ken Iverson, thought that this
"right always preferred" (my phrase, not his) choice is somehow
natural or right. If he had wanted to change that, no discussion
or convincing would have been necessary, because he developed the
original core of (what would later be called) APL by himself.
 
I remember reading somewhere that what evolved into APL was
originally called "Iverson notation", but I don't remember where
that was.
woodbrian77@gmail.com: Sep 30 09:38AM -0700

> decided not to. When I read the title of the article, I
> thought it would be a good title for this thread also...
> better late than never.
 
The C++ Middleware Writer has been available now since
October of 2002. It's been an uphill battle in terms of
convincing people to embrace on-line code generation,
but I'm happy with the progress I've been making.
I'm proud of these programs:
https://github.com/Ebenezer-group/onwards/blob/master/src/cmw/tiers/genz.cc
https://github.com/Ebenezer-group/onwards/blob/master/src/cmw/tiers/cmwA.cc
 
One conclusion, from working on that second program, is I
would like to have an intrusive list available in the standard.

 
If you would indulge me, I'd like to have a little guessing
game as far as what quote I am thinking of in regards to this
milestone. Here are a few hints:
1. It's a famous quote that probably at least 70% of
you are familiar with.
 
2. It's not from the Bible and I don't think I've
mentioned it here previously.
 
I'll give an additional hint with each guess.
 
Thanks for all the fishy and not-so-fishy ideas
over the years on how to improve things.
 
 
Brian
Ebenezer Enterprises - Enjoying programming again.
https://github.com/Ebenezer-group/onwards
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Sep 30 02:41AM +0100

My first political domain/web-site: https://couldhavehadme.com/
 
/Flibble
 
--
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Sep 30 02:41AM +0100

On 29/09/2018 23:54, Rick C. Hodgin wrote:
 
> We've been duped by an enemy working globally against mankind.
 
> https://www.youtube.com/watch?v=zOdpfPmeMIA
 
> 25 minutes to challenge your thinking.
 
You can now no longer even be bothered to attempt to disguise your spam as
something else? Now you just post URLs to random shitty Christian videos?
You are a dick. Just fuck off.
 
/Flibble
 
--
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
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.

Saturday, September 29, 2018

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

"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Sep 29 03:54PM -0700

An excellent teaching outlining how Jesus has been pushed out of our
lives, society, thinking, and even consideration.
 
We've been duped by an enemy working globally against mankind.
 
https://www.youtube.com/watch?v=zOdpfPmeMIA
 
25 minutes to challenge your thinking.
 
--
Rick C. Hodgin
superduperhengyuan@gmail.com: Sep 29 01:16PM -0700

On Saturday, September 29, 2018 at 12:57:26 PM UTC-7, Marcel Mueller wrote:
> allocations - except for those which do not use dynamic memory at all,
> of course.
 
> Marcel
 
Yes, dealing with static globals can be a major issue and there are no fixed solutions. In fact, it could be no solutions at all unless extensive changes are made.
 
One approach is to trigger the initiation of some globals using system malloc / free. Then switch to memory pool for later uses with no caching. For one open source library I used at work, this approach was quite successful and allowed us to do version upgrades of the library with minimal modifications.
 
With memory pool, at least there can be a solution for certain cases with restrictions. This is the point.
"Öö Tiib" <ootiib@hot.ee>: Sep 29 02:31PM -0700

> > quad core.
 
> Hi, currently I did not add locking code. This can be easily added
> later but not a focus.
 
Then it is unfair to compete with malloc and free that are thread-safe.
Have you benchmarked against malloc and free compiled as single-threaded?
 
> The intention is that each thread should have its memory pool through
> thread local or whatever other means.
 
That approach could be thinkable if there was clear distinction from
malloc and free that are not thread-local. Otherwise how we make
difference between things that are made strictly for thread-local
processing and things that may end their life-time in hands of some
other thread? Having such complications would make it error-prone,
but still useful as performance optimization.
 
> want to release all the memory associated with that thread. Can
> we release all the resources associated with that thread. Using
> this memory pool can do so.
 
This scenario would be only thinkable when threads acted like
separate processes, communicating with each other only
through rather restricted means like sockets or pipes or
memory-mapped files of operating system. It is no way the case
with usual multi-threaded programs and it would be likely better
to use actual multi-processing and the processes compiled as
single-threaded in these scenarios.
 
> Obviously, there are other pieces you need to incorporate this memory pool.
 
I did not manage to follow what you meant.
superduperhengyuan@gmail.com: Sep 29 03:47PM -0700

On Saturday, September 29, 2018 at 2:31:34 PM UTC-7, Öö Tiib wrote:
> Then it is unfair to compete with malloc and free that are thread-safe.
> Have you benchmarked against malloc and free compiled as single-threaded?
 
I used the latest dlmalloc source (the mother of most if not all malloc implementations) which does not have lock enabled by default.
 
> processing and things that may end their life-time in hands of some
> other thread? Having such complications would make it error-prone,
> but still useful as performance optimization.
 
An approach is basically have a thread local variables to keep track of memory pool including system malloc/free is being used. And switch to use specific pool using the flag.
 
> with usual multi-threaded programs and it would be likely better
> to use actual multi-processing and the processes compiled as
> single-threaded in these scenarios.
 
Imagine that you are running lots of threads to do some heavy processing.
Each thread has its own partition of work (which may or may not need to call 3rd party library), with some shared data cache, and thread specific memory. Now, one thread declares there is an error / solution and the job can be terminated early. What do you do at this point?
 
One possible solution is to gather the output info and suspend and kill all the threads and release associated resources. I am not saying that this is the only solution, but it certainly is a choice that pushes certain difficult aspects of task/resource management to specific places, rather than spreading it allover the place.
 
Now, you could argue that this type of work "should" be done in process model. I do not want to get into thread vs process debate. However, threads are typically lighter weight, and lower synchronization costs. Resource managements are also simpler.
 
 
> > Obviously, there are other pieces you need to incorporate this memory pool.
 
> I did not manage to follow what you meant.
 
What I meant that you cannot just drop in memory pool and expect it to magically solve the problem. It requires certain architectural designs such that memory pool provides the benefits. For typical non-server applications, one may never need it.
 
For a long running server process, how to avoid memory leak, fragmentation, etc are challenging issues. CookMem is intended to be a part of solutions, rather than the solution by itself.
 
Heng Yuan
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 29 11:13PM +0100

On Sat, 29 Sep 2018 09:01:25 +0200
Ralf Goertz <me@myprovider.invalid> wrote:
[snip]
> dependeing on whether i is int or char. I never had to use int8_t before
> but as I said I was under the impression, that it would be an integral
> and not a char type.
 
A char type is an integral type. (As are signed char, short int, int,
long int, long long int and their unsigned equivalents and bool,
wchar_t, char16_t and char32_t, together with the fixed/minimum sized
integer types, if they exist in the implementation in question):
according to the standard "bool, char, char16_t, char32_t, wchar_t, and
the signed and unsigned integer types are collectively called integral
types". char can be signed or unsigned but it is also a distinct type
from signed char or unsigned char. It has no special status beyond
that.
 
If all you are concerned about is printing char types with C++ streams'
operator << so they print in the same way that ints print, then cast
them to int in your call to operator << for the stream. Given the
length of this thread though I suspect you must be concerned about
something else.
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Sep 29 10:20PM +0100

Possibly most amusing GitHub pull request evar...
 
https://github.com/Microsoft/MS-DOS/pull/1
 
/Flibble
 
--
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
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.

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

superduperhengyuan@gmail.com: Sep 28 08:10PM -0700

CookMem is a a memory context / allocator written in C++11 that can be easily and quickly cleaned up by freeing the segments, rather than doing individual frees. It is extremely useful to deal with third party libraries that can potentially have memory leaks, or to simplify the memory management.
 
The secondary goal of this project is to provide a good enough performance that should be comparable to dlmalloc and its derivatives. In fact, the algorithms and some code used here are mostly based on dlmalloc. I basically took the pain to understand dlmalloc and rewrote the logics in C++. Some key calculations though are kept the same as dlmalloc since there is no point to reinvent wheels.
 
Github page: https://github.com/coconut2015/cookmem
Project documentation: https://coconut2015.github.io/cookmem/index.html
 
It is licensed under APL 2.0.
Paavo Helde <myfirstname@osa.pri.ee>: Sep 29 10:19AM +0300

> CookMem is a a memory context / allocator written in C++11 that can be easily and quickly cleaned up by freeing the segments, rather than doing individual frees. It is extremely useful to deal with third party libraries that can potentially have memory leaks, or to simplify the memory management.
 
Just for curiosity: how do you convince a crappy third-party library to
use this allocator? And how do you know when it's safe to release the
memory?
 
From the first glance it seems it is lacking the standard
std::allocator interface and std::allocator_traits, which makes it
harder to use with non-crappy third-party C++ libraries.
 
Also, how does this compare with other existing pool allocators like the
Boost Pool Library?
superduperhengyuan@gmail.com: Sep 29 12:49AM -0700

On Saturday, September 29, 2018 at 12:19:52 AM UTC-7, Paavo Helde wrote:
 
> Just for curiosity: how do you convince a crappy third-party library to
> use this allocator? And how do you know when it's safe to release the
> memory?
 
The safest approach is to replace malloc / free. It does not matter if the third party library is C or C++. Before calling the third party library, switch malloc / free to use a memory pool. Once the call is finished, destroy the memory pool and switch back to whatever the previous memory pool or malloc / free.
 
You can take a look at how I do the performance test to compare dlmalloc vs CookMem:
 
https://github.com/coconut2015/cookmem/blob/master/performances/
 
 
> From the first glance it seems it is lacking the standard
> std::allocator interface and std::allocator_traits, which makes it
> harder to use with non-crappy third-party C++ libraries.
 
I believe the allocator interface just need a allocate() and deallocate(). So you use cookmem::MemPool as allocator.
 
That said, it is better to just replace malloc / free / new / delete since it is very error prone mixing allocators (or at least my perception is that it is error prone).
 
 
> Also, how does this compare with other existing pool allocators like the
> Boost Pool Library?
 
Before I started working on CookMem, I did look around for similar stuff and nothing like it is available in C++ as open source. Boost Pool is for fixed size allocations. That is why it is quite simple to implement and very limited in functionality.
 
Heng Yuan
"Öö Tiib" <ootiib@hot.ee>: Sep 29 05:41AM -0700


> Github page: https://github.com/coconut2015/cookmem
> Project documentation: https://coconut2015.github.io/cookmem/index.html
 
> It is licensed under APL 2.0.
 
Is my impression correct that it is only useful for single-threaded
software? That might be crippling in world where even phones are
quad core.
Paavo Helde <myfirstname@osa.pri.ee>: Sep 29 08:33PM +0300

>> use this allocator? And how do you know when it's safe to release the
>> memory?
 
> The safest approach is to replace malloc / free. It does not matter if the third party library is C or C++. Before calling the third party library, switch malloc / free to use a memory pool. Once the call is finished, destroy the memory pool and switch back to whatever the previous memory pool or malloc / free.
 
This sounds like enforcing a strictly single-threaded program, is this so?
 
Also, how exactly do you redirect malloc/free dynamically? It's already
pretty tricky enough to do it statically for the whole program,
especially in Windows.
 
This also assumes that the third-party library does not maintain any
internal state which uses dynamic memory, otherwise it might crash badly
in the next call or upon program exit. Not to speak about that a
third-party library may even decide to spawn its own background threads
which might not like if global malloc/free were changed under their feet.
 
>> harder to use with non-crappy third-party C++ libraries.
 
> I believe the allocator interface just need a allocate() and deallocate(). So you use cookmem::MemPool as allocator.
 
> That said, it is better to just replace malloc / free / new / delete since it is very error prone mixing allocators (or at least my perception is that it is error prone).
 
Yet you are proposing mixing allocators *on the fly*! If that's not
error-prone I do not know what is. Imagine having a local std::string
variable in a function which changes the global malloc/free.
 
 
>> Also, how does this compare with other existing pool allocators like the
>> Boost Pool Library?
 
> Before I started working on CookMem, I did look around for similar stuff and nothing like it is available in C++ as open source. Boost Pool is for fixed size allocations. That is why it is quite simple to implement and very limited in functionality.
 
I have implemented a special pooled allocator for parsing and loading
large XML files into memory. This would be a use case for a
variable-size pooled allocator, but definitely this allocator would be
used only for a certain data structure and should not replace the global
malloc. For example, if I throw an exception during the XML parse I do
not want the error message string to be allocated in the pooled allocator!
superduperhengyuan@gmail.com: Sep 29 10:53AM -0700

On Saturday, September 29, 2018 at 5:41:18 AM UTC-7, Öö Tiib wrote:
 
> Is my impression correct that it is only useful for single-threaded
> software? That might be crippling in world where even phones are
> quad core.
 
Hi, currently I did not add locking code. This can be easily added later but not a focus.
 
The intention is that each thread should have its memory pool through thread local or whatever other means.
 
One use case is that if one thread is about to exit, suspended. We want to release all the memory associated with that thread. Can we release all the resources associated with that thread. Using this memory pool can do so.
 
Obviously, there are other pieces you need to incorporate this memory pool.
 
Heng Yuan
superduperhengyuan@gmail.com: Sep 29 11:22AM -0700

To Paavo Helde,
 
I answered the question of single thread in another post. Please refer to that. Although I do forgot to add if the 3rd party library is multithreaded, you obviously would want to avoid using CookMem for now. Most of the time though, the reason we would want to use 3rd party code is because of some utility thing that is usually single threaded.
 
Regarding mixing allocators. There will be complicated cases where you have one allocator that should be freed, and another allocator that is still in use. Here is an example that deals with this situation:
 
https://github.com/coconut2015/cookmem/blob/master/examples/ex_4.cpp
 
Obviously, it is not trivial. At least memory pool provides a tool for you to extract specific stuff out of it before discarding the rest.
 
Now as for shared memory / context by third party libraries. Obviously you will need to be extremely careful. There are initiation related memory, execution related, and the scope of the memory pool needs to be carefully considered. At work, I have encountered situations like this that must be carefully dealt with, but it is definitely doable.
 
Overall, the use of memory pool is not going to be trivial. You need a lot of other pieces (architectural design etc) to even begin using it. Also, it is not supposed to be an end-all-solve-all solution. It is just one solution. That said, sometimes it can be the best solution.
 
Heng Yuan
Marcel Mueller <news.5.maazl@spamgourmet.org>: Sep 29 09:57PM +0200

> The safest approach is to replace malloc / free. It does not matter if the third party library is C or C++. Before calling the third party library, switch malloc / free to use a memory pool. Once the call is finished, destroy the memory pool and switch back to whatever the previous memory pool or malloc / free.
 
This will sadly fail for many libraries as they tend to use internal
caching. I.e. allocate some objects statically when they are needed
first. These objects are used for later library calls.
 
So unless your library is explicitly stated to use /no persistent data
objects/ the resulting program will always have undefined behavior. And
I never have seen a library that guarantees to make no non-temporary
allocations - except for those which do not use dynamic memory at all,
of course.
 
 
Marcel
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Sep 29 11:01AM -0400

On 9/28/2018 6:00 PM, Rick C. Hodgin wrote:
> Satan is only an imitator, Leigh. He's not an originator.
> God had many names, so he imitated God when he invented
> Islam to deceive people into following a false religion.
 
 
The Bible records only three times where the actual voice
of Satan is recorded: (1) when Satan tempted Adam and Eve,
(2) in the book of Job where God talks to Satan, and (3)
when Jesus was being tempted.
 
In those verses Satan revealed his plan for how to deceive
mankind. His m.o. has never changed:
 
(1) "God's not being good enough to you."
(2) "God, you're being too good..."
(3) "If you'll worship me, I'll be better to you
than God is."
 
In (1) Satan said to Adam and Eve "Hath God said you shall
not eat of the fruits of the garden? ... You will not surely
die, for God knows on the day you eat of it you will be like
God, knowing good and evil." Translation: God's holding
out on you. He's withholding His blessing. You need to lis-
ten to me and I'll teach you the true path to enlightenment.
 
In (2) God addresses Satan in Heaven, and Satan responds:
"Does Job worship you for nothing? You have put a hedge
around Him and blessed the work of his hands." Translation:
God, you're too good to Job. If you take away the many
blessings you've given him, he will curse you to your face.
And for act 2, God again addresses Satan and this time when
Satan responds he says, "Skin for skin. A man will give
all he has to save his skin," so God allows Satan to in-
flict his body with great sickness, but he could not take
his life. Satan covers Job's body with hideous and pain-
ful boils from the soles of his feet to the crown of his
head. But in all of this, when all his possessions were
taken away, and when his health was completely miserable,
never did Job curse God, nor reject Him.
 
In (3) Satan comes to tempt Jesus in the wilderness. He
says, "You see all this? It has been given to me, and I
can give it to whomever I choose. If you will bow down
and worship me, I will give you all these kingdoms."
Translation: God would never give you all this. If you
want to have true riches, you must come to me, for I am
willing to bless you beyond that which God will.
 
In each of these cases you see Satan pitting man against
God, God against man, and then Satan steps in to be the
good guy.
 
In Islam, it's the same m.o. Islam charges that Christianity
had become corrupted, and Allah had to step in to undo the
multitude of corruptions, correcting what the false Christian
church had done in error for centuries.
 
Islam introduces division between the Jewish and Christian
God and man, and between man and their faith, and then swoops
in to be the solution, just like in the 1..2..3 example he's
always used.
 
-----
Jesus denied Satan's offer, and we read in Matthew 28:18
that after Jesus completed the work of God at the cross,
and was raised on the third day, all power and authority
in Heaven and on the Earth (not just the kingdoms of the
Earth Satan was offering) have been given to Jesus.
 
For each of us, but turning away from Satan and following
only after God the Father, His Son Jesus Christ, and the
Holy Spirit, so are we doing rightly here in this world,
and we will receive the full reward after we leave this
world.
 
It comes down to the gift of faith given by God to all
who are being saved. You will know if God is calling you
to be saved on the inside of your heart. He presents Him-
self in a way that you can uniquely identify and know that
it is His call, and not some deception. You will also
read these words and here a confirmation in your spirit,
which is being awakened by God as He alone is the giver of
life, both of physical life, and of spiritual life, and
that new understanding you discern coming into your life,
the way you are realizing that you're looking at things
differently than you use to, it's all evidence of the work
of God in your spirit in your life, which will culminate
in you coming to Jesus in repentance, asking forgiveness
for your sin, and receiving eternal life, and being forever
changed here in this world to start, and then on into
eternity.
 
Consider the songs taught by the enemy of God through
sinful men and women. Pick the top 10 songs of any year
and go through the lyrics and compare them to the teach-
ings of the Bible, and of the guidance by the Holy Spirit.
 
You'll find that of those top 10 they are either teaching
directly against God's teachings, or are fairly neutral
and serve as gateway songs to get you to buy the album so
you can then hear the teachings later which are false in
the rest of the songs.
 
Very rarely in anything mainstream will see Christ pre-
sented properly. Even in TV shows like When Calls The
Heart on Hallmark Channel, which has an early 1900s set-
ting, and a relatively strong Christian presence in the
community, still when they quote Bible verses they do
not quote them accurately. They'll say "Corinthians"
when they cite something, rather than "1st Corinthians"
or "2nd Corinthians." They use the term "good book"
rather than the Bible, etc.
 
The true God of the universe, God the Father, God the
Son, God the Holy Spirit, is being suppressed in this
world by the enemy, who wants to keep us following after
him, after sin, after wrong things, so he can keep us
trapped on that road to Hell, in unrepentance, under
condemnation, in judgment, etc.
 
I urge you to investigate these things and see for
yourself. Go to the pages of scripture and read for
yourself the teachings of the Holy Spirit, and see if
they align with the things of this world, explaining
it exactly, and see if you can't also see that division
which exists between the people who follow after God in
this world, and the enemy who seeks to have us following
after him in God's place.
 
--
Rick C. Hodgin
Mr Flibble <flibbleREMOVETHISBIT@i42.co.uk>: Sep 29 04:58PM +0100

On 29/09/2018 16:01, Rick C. Hodgin wrote:
> On 9/28/2018 6:00 PM, Rick C. Hodgin wrote:
[snip] (tl;dr)
 
Fucktard who thinks that Satan invented fossils, fuck off.
 
/Flibble
 
--
"Suppose it's all true, and you walk up to the pearly gates, and are
confronted by God," Bryne asked on his show The Meaning of Life. "What
will Stephen Fry say to him, her, or it?"
"I'd say, bone cancer in children? What's that about?" Fry replied.
"How dare you? How dare you create a world to which there is such misery
that is not our fault. It's not right, it's utterly, utterly evil."
"Why should I respect a capricious, mean-minded, stupid God who creates a
world that is so full of injustice and pain. That's what I would say."
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Sep 29 10:39AM -0700

On Saturday, September 29, 2018 at 11:59:05 AM UTC-4, Mr Flibble wrote:
> On 29/09/2018 16:01, Rick C. Hodgin wrote:
> > On 9/28/2018 6:00 PM, Rick C. Hodgin wrote:
> [snip] (tl;dr)
 
Was posted for those who can hear the truth, and are being saved.
 
> .. who thinks that Satan invented fossils, .. .
 
Never said that. Don't believe it. Fossils exist. They are not
millions/billions of years old. That's the lie.
 
--
Rick C. Hodgin
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Sep 29 01:21PM -0400

Totally off-topic post, but if you like technology (hardware and/
or software) you may find it interesting. It's on Netflix, and a
TV station in Canada (where it was produced).
 
==> Spoilers! Just read the top part before the episode listing:
https://en.wikipedia.org/wiki/ReBoot:_The_Guardian_Code
 
I have found this new TV show interesting. It's a Netflix original
about four high school students drafted into service inside cyber-
space. They enter a special room with something like a transporter
pad from Star Trek, but instead of beaming someplace else, they beam
into cyberspace as code (the "Guardian Code"). There, they are
drafted into service and fight viruses and enemies.
 
If you remember the TV show ReBoot from the 1990s, this is a reboot
of that show. It has a notably different flavor. MegaByte is back
with an upgrade. We get to see Dot and Enzo, Bob and Hexadecimal,
all in MainFrame, which is one part of cyberspace the Guardians go
to.
 
-----
It's one of the best Sci-Fi shows I've ever seen.
 
Netflix released episodes 1-10 earlier this year as season 1, and
have just released episodes 11-20 as season 2. In Canada, the whole
series has been available for a few months.
 
This apparently will be the end of the series as I do not believe
it's been picked up for another season, but, it is such a well-writ-
ten show. The concepts are creative and the 3D scenes in cyberspace
are all done using the UNREAL gaming engine. When cyber-locusts at-
tack, they're using the gaming engine's AI to coordinate their fly-
ing so they don't collide with one another, nor the scene. It al-
lowed them to have such high volumes of animated characters, accord-
ing to an interview I saw on YouTube earlier this year.
 
The show begins by laying down some basic concepts, and some of the
acting is weak in the first few episodes in my opinion, but it picks
up mid-first season, and the story line is very compelling. The
actress who plays V.E.R.A, and the actor who plays Sourcerer (the
main bad guy) ... they deserve awards for their roles.
 
I'm on episode 6 of season 2. Episodes 11+ really amp up the show.
I would like to see a season 3 pickup.
 
If you like Sci-Fi, I think you might really like this show. I'd
be curious to hear some reviews about it. Please email me privately
if you prefer.
 
Thank you.
 
--
Rick C. Hodgin
David Brown <david.brown@hesbynett.no>: Sep 29 01:44PM +0200

On 28/09/18 22:23, Öö Tiib wrote:
> iOS device than formula (1). I surely checked that it was also
> better in particular case (lot of verifying if points were in
> ranges or not) on Mac.
 
The two formula are close to equivalent, but not entirely. They
certainly rely on the condition that a <= c, and may be different in
cases near wrappings (I haven't thought about it enough to tell).
 
I would want compilers to make such transformations when it makes a
difference and it is known to be correct - I don't want to have to start
messing with these myself. I have certainly seen gcc make such
transformations.
 
I also expect compilers to make the right choice between code with
conditional jumps and alternatives such as conditional moves. In some
cases, branches are cheaper (even on modern OOO cpus) - in other cases,
they are more expensive. What is almost certainly true is that the
compiler writers know more about it than the average C++ programmer.
 
 
So write your source code in the clearest and most logical manner. Then
if you are convinced the compiler is generating sub-optimal code, file a
"missed optimisation" bug for it.
"Öö Tiib" <ootiib@hot.ee>: Sep 29 07:14AM -0700

On Saturday, 29 September 2018 14:44:18 UTC+3, David Brown wrote:
 
> The two formula are close to equivalent, but not entirely. They
> certainly rely on the condition that a <= c, and may be different in
> cases near wrappings (I haven't thought about it enough to tell).
 
Exactly! The formulas can give different results when the length
overflows (undefined behavior) or when it is negative. On case
of ranges such situations are programming errors and should be
dealt with where the ranges are formed, but with just any a, b, c
these are perfectly legal situations.
 
> cases, branches are cheaper (even on modern OOO cpus) - in other cases,
> they are more expensive. What is almost certainly true is that the
> compiler writers know more about it than the average C++ programmer.
 
C++ compiler does not understand concept of ranges. At least not
before "Concept" of "Range" is added to it. ;) It is up to its
implementers to make std::vector as 3 pointers or pointer and 2
lengths but it can't decide if we store representation of our
"ranges" as start and end pair or as start and length pair.
 
Latter was optimal on described case, but it may be sub-optimal
on some other.
 
Now if we choose start and length then it still does not understand
what these are and so it can not convert 'a < b && b < a + len'
into '(unsigned)(b - a) < len' because negative 'len' may make
sense in some other context and then the formulas are different.
 
 
> So write your source code in the clearest and most logical manner. Then
> if you are convinced the compiler is generating sub-optimal code, file a
> "missed optimisation" bug for it.
 
I generally write code in most simple and logical manner because it is
only about 5% of it that can possibly alter perceivable performance.
The attempt here was to post something thought-provoking
as alternative to stuff from ramine, leigh and rick that does
not matter any to me.
Richard Damon <Richard@Damon-Family.org>: Sep 29 01:09PM -0400

On 9/27/18 4:41 PM, Vir Campestris wrote:
 
> APL is burned into my brain. I'm scarred by it - traumatised even.
 
> It was strict right to left evaluation. No precedence.
 
> Andy
 
I presume APL didn't try to define an operator precedence because it has
SO many operators no one could agree on an order, let alone attempt to
remember it.
Ralf Goertz <me@myprovider.invalid>: Sep 29 09:01AM +0200

Am Fri, 28 Sep 2018 09:28:30 -0700 (PDT)
 
> The std::byte has all bitwise arithmetic operators defined. What you
> mean by "formatted input"? Sure, when our use case needs something
> extra or different then that can be written.
 
That was the whole point why I started this thread. I need
set<vector<some_integral_type>> e.g. for counting certain permutations.
Sometimes the range of values exceeds what fits in a byte, then I have
to use 16 or 32 bit types. In some cases 8 bit is enough but there are
so many vectors in that set that I get into memory trouble when using 16
bit. That's why I templated my program. Then I fell into the operator
overload trap that cin>>i means something completely different
dependeing on whether i is int or char. I never had to use int8_t before
but as I said I was under the impression, that it would be an integral
and not a char type. Finding out that it is nothing but a typedef to
char made to curious as to what good this typedef does.
 
std::byte seemed promising to me, but as far as I can tell there is
neither a an overload of e.g >>
 
error: no match for 'operator>>' (operand types are 'std::istream' {aka
'std::basic_istream<char>'} and 'std::byte')
 
which I mean by formatted input nor can I do something like b%=42 when b
is a std::byte. That's what I mean by arithmetics.

 
> James Kuyper gave perfect answer to that. Note that exactly because
> of such magical silent promotions and conversions sometimes some code
> will give unexpected diagnostics or results.
 
Thanks, James. But what difference does that make? If the short operands
get promoted to int and the result gets demoted to short, can that
really be different from doing it directly? The program
 
 
#include <iostream>
#include <limits>
 
int main() {
typedef int Int;
Int i1(std::numeric_limits<short int>::max());
Int i2(i1/2);
Int i=i1+i2;
std::cout<<i1<<" "<<i2<<" "<<static_cast<short int>(i)<<std::endl;
}
 
prints
 
32767 16383 -16386
 
here regardless of whether Int is int or short int. Can the observable
behaviour really be different (you said unexpected results)? I get that
the platform may or may not support the addition of shorts directly. But
isn't that merely an implementation detail?
David Brown <david.brown@hesbynett.no>: Sep 29 02:06PM +0200

On 28/09/18 18:28, Öö Tiib wrote:
 
> The std::byte has all bitwise arithmetic operators defined. What you
> mean by "formatted input"? Sure, when our use case needs something
> extra or different then that can be written.
 
I have always thought that was a bad idea. std::byte should have been
pure "raw memory" - a type you can use to read or write anything,
accessing any data for reading and writing (replacing the "char" types
from C for things like memcpy), and being a "pointer to memory". It is
/almost/ such a type, but bitwise operators have no place in such a type.
"Öö Tiib" <ootiib@hot.ee>: Sep 29 05:11AM -0700

On Saturday, 29 September 2018 10:01:35 UTC+3, Ralf Goertz wrote:
> 'std::basic_istream<char>'} and 'std::byte')
 
> which I mean by formatted input nor can I do something like b%=42 when b
> is a std::byte. That's what I mean by arithmetics.
 
These are not there because most sane software does not need those.
Take few steps back, I try once more to explain the big picture that
may help you out of that puzzle (or not). ;)
 
Rules of thumb:
1) For text input/output and for arithmetic processing use only
(u)int32_t, (u)int64_t, double and/or custom fast arithmetic
classes.
 
2) For binary input/output and with large storage use packing
level that is optimal. Optimal may be not to pack at all or
to go down to exact bit positions or even further depending
on bang needed and buck available.
 
The explanations of above rules:
1) When not constrained with I/O then the text formats like
JSON are most convenient. But narrow data types are still bad
for processing. The modern processors do not usually have
instructions for narrow data types. So these have to unpack
from narrow types and later pack back and therefore running
complex computations on narrow types is slower than with
already unpacked fast types. Packed data that is being
under heavy processing cripples.
 
2) The processors are fast on modern platforms so bandwidth and
throughput and latency of communications with anything
(including RAM) can't often feed those with enough data. That is
the common bottle-neck. If that is the case then it can be
profitable to go down to bits or even farther than that
with packing.
However do not reinvent wheels there, use existing formats.
For example most multimedia is packed about 50 times so average
byte of it is packed into about 0.16 bits. For other example
unpacking with the Lempel–Ziv–Welch (LZW) algorithm (Patent
expired on June 20, 2003) can be faster than memcpy() from
unpacked buffer.
 
The conclusions from those points above:
Attempt to read std::byte from text input is breaking all logic!
There are whopping 4 bytes (3 numbers and separator) used in
slow communication that is then turned into inefficient for
processing packed format (a byte). If text is used because of nature
of channel then use Base64 to transferring bytes.
 
 
> Thanks, James. But what difference does that make? If the short operands
> get promoted to int and the result gets demoted to short, can that
> really be different from doing it directly?
 
There is poster supercat in comp.lang.c who loves to post examples
about that. He has only few of those IIRC like that:
 
unsigned mul(unsigned short a, unsigned short b) {return a*b;}
 
The examples of supercat are of interest to me only as stuff that
smells, how to estimate amounts of potential improvements or
simplifications that can be made and likely impact of those.
 
If to follow the "rules of thumb" that I posted above then we
actually do not need these narrow types for anything else
but only when we are constrained with storage or communications.
And then we use these only for converting into larger types
for processing and back for storing. Only sometimes when we
really pack or convert on bit level or further we will need
bitwise operations that std::byte implements for us already.
"Öö Tiib" <ootiib@hot.ee>: Sep 29 05:25AM -0700

On Saturday, 29 September 2018 15:06:31 UTC+3, David Brown wrote:
> accessing any data for reading and writing (replacing the "char" types
> from C for things like memcpy), and being a "pointer to memory". It is
> /almost/ such a type, but bitwise operators have no place in such a type.
 
I see a point of bitwise operations with bytes only for bit-wise
altering the data to fit with some binary layout. That may mean
things like array of 12 bit wide ints packed into a block of bytes
without any padding or results of other such packing algorithms.
Subtracting, adding, multiplying and dividing however feel totally
useless.
"Öö Tiib" <ootiib@hot.ee>: Sep 28 04:33PM -0700

On Saturday, 29 September 2018 01:44:59 UTC+3, Paul wrote:
> It's also not a chocolate biscuit.
 
> It is a design pattern, though.
 
> So I was asking the name of the design pattern.
 
I try to express it then through analogy. Room design patterns are meant
for purpose, for certain activities in those rooms, you know bathroom,
toilet, kitchen, bedroom, living room, studio, garage &c.
Similarly software module design patterns are meant for certain purpose
for running certain algorithms in those modules. Creational design
patterns are for constructing certain types of data, structural design
patterns are for composing relations between objects to acquire
certain functionality and behavioral patterns are also for purpose
usually about communication between objects. So all of it is
about purposeful activities. If there are no purpose then there are
no pattern.
Paul <pepstein5@gmail.com>: Sep 28 05:02PM -0700

On Saturday, September 29, 2018 at 12:33:14 AM UTC+1, Öö Tiib wrote:
> usually about communication between objects. So all of it is
> about purposeful activities. If there are no purpose then there are
> no pattern.
 
The problem is that you have a class B and you want to encapsulate the
idea of "a particular instantiation of class B"
So one idea is to use another class to encapsulate the idea of
"a particular instantiation of class B"
 
So I use class A for that purpose.
 
I'll try to be a bit more concrete --
 
int f(double w, double x, double y, double z)
is an intricate mathematical function
 
B is a class for calculating f.
 
The problem is to illustrate this procedure for the numbers
1.1, 2.3, 4.5, 5.6 -- call the corresponding vector vec.
 
So I write
 
class B
{
public:
B(const std::vector<double>&);

protected:
int f(); // Computes f with respect to 4-dim vector in constructor
};
 
class A : public B
{
 
public:
A();
 
int F();
}
 
A::A() : B(vec)
{
 
}
 
int A::F()
{
return f();
}
 
int main()
{
A a;
std::cout << a.F() << " is the value of f when applied to the
illustrative parameters in vec ";
}
"Öö Tiib" <ootiib@hot.ee>: Sep 28 05:40PM -0700

On Saturday, 29 September 2018 03:02:16 UTC+3, Paul wrote:
> std::cout << a.F() << " is the value of f when applied to the
> illustrative parameters in vec ";
> }
 
Whole class for very concrete instantiation? That is done usually only
in unit tests. So pattern is "mock wrapper for unit testing" or
something like that.
Jorgen Grahn <grahn+nntp@snipabacken.se>: Sep 29 06:46AM

On Fri, 2018-09-28, Paul wrote:
> I have a class A which implements an instantiation of class B with
> some default parameters.
 
I had trouble reading that sentence. How is it different from
"A specializes B, by simplifying its construction"?
 
Also, would a plain function work for you?
 
B A() { return B(C(D(OtherParams))); }
 
...
 
/Jorgen
 
--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .
Paul <pepstein5@gmail.com>: Sep 29 02:15AM -0700

On Saturday, September 29, 2018 at 7:47:02 AM UTC+1, Jorgen Grahn wrote:
 
> Also, would a plain function work for you?
 
> B A() { return B(C(D(OtherParams))); }
 
> ...
 
I should have said "A specializes B by simplifying its construction."
That's better. Thanks.
 
And thanks to Oo Tiib too
 
And thanks to everyone else.
 
Paul
"😉 Good Guy 😉" <hello.world@example.com>: Sep 29 02:07AM +0100

*Roslyn*is the codename-that-stuck for the open-source compiler for C#
and Visual Basic.NET. Here's how it started in the deepest darkness of
last decade's corporate Microsoft, and became an open source,
cross-platform, public language engine for all things C# (and VB, which
I'll take as a given for the rest of this piece).
 
<https://medium.com/microsoft-open-source-stories/how-microsoft-rewrote-its-c-compiler-in-c-and-made-it-open-source-4ebed5646f98>
 
Good luck.
 
 
--
With over 950 million devices now running Windows 10, customer
satisfaction is higher than any previous version of windows.
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.