Monday, March 20, 2017

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

Juha Nieminen <nospam@thanks.invalid>: Mar 20 08:03AM

> linker, and runtime messages
> ??? Make sure main() has a return type of int, not void!
> </FAQ 5.8 question about code that doesn't work>
 
Most of those are really nitpicky.
 
If the implementation of some example function is completely irrelevant
to the question at hand, then it can very well be left empty. (Sure, it
may be better to just declare the function rather than define it with a
"..." implementation, but complaining about it would be really nitpicky.)
 
In simple examples, standard #include lines aren't really needed.
 
If the question relates to standard C++, posting the version number of a
compiler is completely irrelevant.
 
And so on.
"K. Frank" <kfrank29.c@gmail.com>: Mar 20 05:10AM -0700

Hello Alf and Group!
 
On Saturday, March 18, 2017 at 9:07:28 PM UTC-4, Alf P. Steinbach wrote:
> find it. As I recall that charter defined as off-topic postings about
> how to use any particular API: a flood of Windows API postings in
> comp.lang.c++ was a main reason that the moderated group was created.
 
The signal-to-noise ratio of this group (comp.lang.c++)
ebbs and flows over time. We seem to be at a relative
low point (due, I think, both to decreased signal -- maybe
because of other discussion forums -- and, for whatever
reason, to increased noise).
 
Would it make sense to consider rejuvenating the former
companion group, comp.lang.c++.moderated?
 
 
> However, in 2017, with very high traffic not a problem, I think
> comp.lang.c++ should be far more inclusive. That's just my personal
> opinion, of course, but I state it as possibly a point of discussion.
 
Whether comp.lang.c++ or comp.lang.c++.moderated, I agree
that "legitimate" topics for c++ discussion could go beyond
the narrow criterion you quoted from the FAQ Lite.
 
> Cheers!,
 
> - Alf
 
 
Happy Posting!
 
 
K. Frank
bitrex <bitrex@de.lete.earthlink.net>: Mar 20 10:46AM -0400

On 03/20/2017 08:10 AM, K. Frank wrote:
 
> low point (due, I think, both to decreased signal -- maybe
> because of other discussion forums -- and, for whatever
> reason, to increased noise).
 
I think a lot of people went to sites like Stack Overflow, and for a
time, things were good.
 
Then the inmates took over the asylum, and it seemed to decide its
mission was not to be a Q&A site for programming questions, but a
repository of all "common programming questions" to be guarded and
maintained such that any Google search on say "what's a smart pointer
for" would bring it up in the top list of hits.
 
And the team of moderators and "power users" is such that trying to turn
the clock back on it is just too painful. It's near impossible to ask
even a well-thought-out question without someone or other on the
high-rep crew showing up to get their shot in: "why would you do this",
"if anyone wrote this kind of code at my place there'd be hell to pay",
and other forms of essentially "u suck at teh codez" "answers."
 
bitrex <bitrex@de.lete.earthlink.net>: Mar 20 10:54AM -0400

On 03/20/2017 10:46 AM, bitrex wrote:
> high-rep crew showing up to get their shot in: "why would you do this",
> "if anyone wrote this kind of code at my place there'd be hell to pay",
> and other forms of essentially "u suck at teh codez" "answers."
 
That is to say when you design a system based around concepts of
"reputation" and "badges" and "status", it seems not big surprise that
those who drift to the top of the system are likely to be simply the
most status-obsessed who find effective ways to game that system, not
necessarily those who provide the most valuable contributions. ;-)
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 20 05:17PM +0100

On 20-Mar-17 9:03 AM, Juha Nieminen wrote:
 
> If the question relates to standard C++, posting the version number of a
> compiler is completely irrelevant.
 
> And so on.
 
No, it has to do with reproducible, and that the person asking is
usually the last competent to decide what to leave out.
 
Cheers!,
 
- Alf
woodbrian77@gmail.com: Mar 20 09:20AM -0700

On Saturday, March 18, 2017 at 8:07:28 PM UTC-5, Alf P. Steinbach wrote:
 
Please don't swear here.
 
 
Brian
Ebenezer Enterprises
http://webEbenezer.net
legalize+jeeves@mail.xmission.com (Richard): Mar 20 04:27PM

[Please do not mail me a copy of your followup]
 
"K. Frank" <kfrank29.c@gmail.com> spake the secret code
 
>Would it make sense to consider rejuvenating the former
>companion group, comp.lang.c++.moderated?
 
+1
 
I just had to add another idiot to my KILL file this morning. 88
unread messages when I started and over 50% were ditched by filtering.
 
I'd join a group of moderators for such a group as long as I didn't
have to do it alone.
--
"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>
Daniel <danielaparker@gmail.com>: Mar 20 09:40AM -0700

On Monday, March 20, 2017 at 8:10:33 AM UTC-4, K. Frank wrote:
 
> Would it make sense to consider rejuvenating the former
> companion group, comp.lang.c++.moderated?
 
+1
"Chris M. Thomasson" <invalid@invalid.invalid>: Mar 19 05:42PM -0700

This queue can be spiced up with exotic C++ atomics and such, but for
now, lets focus on this simple construct:
 
A simple fifo thread-safe queue, based on mutexs, condvars, and a c++
deque. This queue is actually multi-producer/consumer, but the test
example code uses a single producer. Also, it uses a special mutex to
make sure calls to printf are thread-safe! ;^)
 
http://pastebin.com/raw/GA9pJvKN
(pastebin link without ads! ;^)
 
<code>
_________________________________________
#include <cstdio>
#include <deque>
#include <condition_variable>
#include <mutex>
#include <memory>
#include <thread>
#include <algorithm>
#include <cassert>
 
 
template<typename T>
struct queue
{
typedef std::deque<T> raw_queue_t;
 
raw_queue_t m_queue;
std::condition_variable m_cond;
std::mutex m_mutex;
 
void push(T const& obj)
{
{
std::unique_lock<std::mutex> lock(m_mutex);
m_queue.push_back(obj);
}
 
m_cond.notify_one();
}
 
T pop()
{
T front;
 
{
std::unique_lock<std::mutex> lock(m_mutex);
while (! m_queue.size()) m_cond.wait(lock);
front = m_queue.front();
m_queue.pop_front();
}
 
return front;
}
};
 
 
typedef queue<unsigned int> string_queue_t;
#define CONSUMERS 5
#define N 1000
 
 
void producer(std::mutex& std_out_mtx, string_queue_t& queue)
{
{
std::unique_lock<std::mutex> lock(std_out_mtx);
std::printf("producer::queue::(%p) - enter\n", (void*)&queue);
}
 
for (unsigned int i = 0; i < N; ++i)
{
queue.push(i + 1);
std::this_thread::yield(); // just for some spice
}
 
for (unsigned int i = 0; i < CONSUMERS; ++i)
{
queue.push(0);
std::this_thread::yield(); // just for some spice
}
 
{
std::unique_lock<std::mutex> lock(std_out_mtx);
std::printf("producer::queue::(%p) - exit\n", (void*)&queue);
}
}
 
 
void consumer(unsigned int id, std::mutex& std_out_mtx, string_queue_t&
queue)
{
{
std::unique_lock<std::mutex> lock(std_out_mtx);
std::printf("consumer(%u)::queue::(%p) - enter\n", id,
(void*)&queue);
}
 
unsigned int prev = 0;
 
for (;;)
{
unsigned int msg = queue.pop();
 
{
std::unique_lock<std::mutex> lock(std_out_mtx);
std::printf("consumer(%u)::msg::(%u)\n", id, msg);
}
 
if (msg == 0) break;
 
assert(msg > prev); // validate fifo nature
 
prev = msg;
}
 
{
std::unique_lock<std::mutex> lock(std_out_mtx);
std::printf("consumer::queue::(%p) - exit\n", (void*)&queue);
}
}
 
 
int main(void)
{
{
string_queue_t queue;
std::mutex std_out_mutex;
 
std::thread consumers[CONSUMERS];
 
for (unsigned int i = 0; i < CONSUMERS; ++i)
{
consumers[i] = std::thread(
consumer,
i,
std::ref(std_out_mutex),
std::ref(queue)
);
}
 
std::thread producer_thread(
producer,
std::ref(std_out_mutex),
std::ref(queue)
);
 
producer_thread.join();
 
for (unsigned int i = 0; i < CONSUMERS; ++i)
{
consumers[i].join();
}
}
 
std::printf("\nComplete, hit <ENTER> to exit...\n");
std::fflush(stdout);
std::getchar();
 
return 0;
}
_________________________________________
 
 
Any thoughts?
 
Can anybody run this pile? ;^o
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 20 05:07AM +0100

On 20-Mar-17 1:42 AM, Chris M. Thomasson wrote:
> _________________________________________
 
> Any thoughts?
 
> Can anybody run this pile? ;^o
 
It works with MinGW g++ 6.3.0 and Visual C++ 2017, but Windows Defender
detects the executable from Visual C++ as "Trojan: Win32/Fuery.B!cl"…
 
:)
 
Cheers!,
 
- Alf
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Mar 20 06:37AM +0100

On 20-Mar-17 1:42 AM, Chris M. Thomasson wrote:
> make sure calls to printf are thread-safe! ;^)
 
> http://pastebin.com/raw/GA9pJvKN
> (pastebin link without ads! ;^)
 
[snip code]
 
I re-expressed the code in the current Expressive C++ dialect (very
experimental and subject to change at any whim of mine), as now
partially documented at
 
<url: https://github.com/alf-p-steinbach/Expressive-Cpp/>
 
Dealing with your code prompted me to define $with and $with_var
statements, used below.
 
The code got shorter and IMHO a little more clear.
 
 
<code>
#include <stdio.h>
#include <deque>
#include <condition_variable>
#include <mutex>
#include <memory>
#include <thread>
#include <algorithm>
#include <assert.h>
using namespace std;
 
template< class T >
class Queue_
{
private:
deque<T> m_queue;
condition_variable m_cond;
mutex m_mutex;
 
public:
$p push( ref_<const T> obj )
{
$with( unique_lock<mutex>( m_mutex ) ) m_queue.push_back(obj);
m_cond.notify_one();
}
 
$f pop() -> T
{
T front;
$with_var( lock, unique_lock<mutex>( m_mutex ) )
{
while( m_queue.size() == 0 ) m_cond.wait( lock );
front = m_queue.front();
m_queue.pop_front();
}
return front;
}
};
 
using String_queue = Queue_<unsigned int>;
const int n_consumers = 5;
const int N = 1000;
 
$p producer(
ref_<mutex> std_out_mtx,
ref_<String_queue> queue
)
{
$with( unique_lock<mutex>( std_out_mtx ) )
printf("producer::queue::(%p) - enter\n", (void*)&queue);
 
for( $each i $in up_to( N ) )
{
queue.push( i + 1 );
this_thread::yield(); // just for some spice
}
 
for( $n_times( n_consumers ) )
{
queue.push( 0 );
this_thread::yield(); // just for some spice
}
 
$with( unique_lock<mutex>( std_out_mtx ) )
printf("producer::queue::(%p) - exit\n", (void*)&queue);
}
 
$p consumer(
const unsigned id,
ref_<mutex> std_out_mtx,
ref_<String_queue> queue
)
{
$with( unique_lock<mutex>( std_out_mtx ) )
printf("consumer(%u)::queue::(%p) - enter\n", id, (void*)&queue);
 
unsigned prev = 0;
 
$loop
{
const unsigned msg = queue.pop();
 
$with( unique_lock<mutex>( std_out_mtx ) )
printf("consumer(%u)::msg::(%u)\n", id, msg);
 
if( msg == 0 ) break;
 
assert( msg > prev ); // validate fifo nature
prev = msg;
}
 
$with( unique_lock<mutex>( std_out_mtx ) )
printf("consumer::queue::(%p) - exit\n", (void*)&queue);
}
 
$just
{
String_queue queue;
mutex std_out_mutex;
 
raw_array_of_<n_consumers, thread> consumers;
 
for( $each it $in enumerated( consumers ) )
{
it.item() = thread(
consumer,
it.index(),
ref( std_out_mutex ),
ref( queue )
);
}
 
thread producer_thread(
producer,
ref( std_out_mutex ),
ref( queue )
);
 
producer_thread.join();
 
for( $each_object t $in consumers ) { t.join(); }
}
</code>
 
 
Cheers!,
 
- Alf
Bonita Montero <Bonita.Montero@gmail.com>: Mar 20 10:32AM +0100

Your queue lacks a pop() with a timeout - like the ConcurrentLinkedQueue
in Java.
 
--
http://facebook.com/bonita.montero/
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Mar 20 01:13PM

On Sun, 19 Mar 2017 17:42:13 -0700
> example code uses a single producer. Also, it uses a special mutex to
> make sure calls to printf are thread-safe! ;^)
 
> http://pastebin.com/raw/GA9pJvKN
 
For a generic thread safe queue using the standard containers, I would
generally use a list rather than a deque and splice the new item in
when pushing. This means that if T has a copy constructor which
allocates, the allocation takes place outside the queue mutex so
substantially reducing contention (all that is done under the mutex is
to splice, which only swaps some pointers). I say "generic" because if
you know T will be a fundamental type or an aggregate of fundamental
types, a deque would be better.
 
Doing a similar splice operation in the pop() method to minimize
contention does however mean sacrificing strong exception safety if the
queue item type's move assignment operator (or if it has none, its
copy assignment operator) might throw. So it is a matter of design
whether you want to de-queue using splicing also, or offer that as an
option.
 
Apropos of strong exception safety, your pop() method's strong
exception safety relies on RVO. That is OK I guess with C++17 which has
mandatory RVO (technically I don't think that the standard guarantees
that std::deque::pop_front() does not throw, but it seems inconceivable
that it would if the queue item's destructor does not throw). In
earlier times strong exception safety would have been dealt with by
pop() taking a T& out parameter so the popped object is not copied or
moved twice.
 
You might well want rate-limiting on a queue of this kind to prevent
producers overrunning consumers. That introduces all sorts of other
trade-offs.
 
Chris
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Mar 20 02:45PM

On Mon, 20 Mar 2017 13:13:37 +0000
Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote:
[snip]
> throw). In earlier times strong exception safety would have been
> dealt with by pop() taking a T& out parameter so the popped object is
> not copied or moved twice.
 
On looking at N4640 (§12.8.3), I am not now convinced that RVO is
required by C++17 for named return values of this kind:
 
"In a return statement in a function with a class return type, when
the expression is the name of a non-volatile automatic object (other
than a function parameter or a variable introduced by the
exception-declaration of a handler (15.3)) with the same type
(ignoring cv-qualification) as the function return type, the
copy/move operation CAN be omitted by constructing the automatic
object directly into the function call's return object" (my emphasis)
 
"Copy elision is required where an expression is evaluated in a
context requiring a constant expression (5.20) and in constant
initialization (3.6.2). [Note: Copy elision might not be performed
if the same expression is evaluated in another context. — end note]"
 
gcc-6.3 does in fact optimize on your code, so providing strong
exception safety. I do not have any older compilers to test at the
moment but out of interest I will try at the end of the week when I
will have some of the gcc-4.* versions available to me. I suspect that
the mutex release before the return statement may inhibit it in some
previous compilers.
 
So I would be inclined to use an out parameter here.
 
Chris
Juha Nieminen <nospam@thanks.invalid>: Mar 20 07:40AM

> Use a traditional link list. You can insert anywhere inexpensively.
 
No, you can't.
 
If you think you can, then prove it. Give me a function that will take
a linked list and a value, and will insert the value in the middle of
the list inexpensively.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Mar 20 05:32AM -0700

On Monday, March 20, 2017 at 3:40:30 AM UTC-4, Juha Nieminen wrote:
 
> If you think you can, then prove it. Give me a function that will take
> a linked list and a value, and will insert the value in the middle of
> the list inexpensively.
 
To be truly inexpensive, you have to have the pointer to the place you
already want to insert it at, but the process goes like this:
 
Object is comprised of pointers:
[<--prev]
[next-->]
 
You have the original object:
obj.prev
obj.next
 
This involves three logical items in the linked list, but only two
of them will be in play depending on whether or not you are inserting
before or after:
left // Before only
target // Before and after
right // After only
 
And when you want to insert something in the middle, it involves
a fourth item, which is always in play:
new
 
So, to complete an operation of adding into a linked list, you
perform these steps, assuming you want to insert before the
target:
 
(1) Create new, and connect (operations broken out here):
(2) left->next = new
(3) new->prev = left
(4) new->next = target
(5) target->prev = new
 
And if inserting after:
 
(1) Create new, and connect (operations broken out here):
(2) right->prev = new
(3) new->next = right
(4) new->prev = target
(5) target->next = new
 
No matter where you insert in the middle, those are your operations.
If you insert at the end or at the beginning, you may also need to
update parent information about the first and last members, otherwise
the operation is the same except you don't hook up things which point
to NULL. You can either do that as an explicit alternate step for
beg/end operations, or you can just check for NULL pointers on left
and right operations on each add and use a single algorithm.
 
There is some machine expense in this operation because you don't
know where in memory these items will be added. But that is also
negated by using a builder to pre-allocate a block of memory to
contain large groups of link-list objects so when you traverse they
are in large chunks sequentially in memory. In such a case you can
also then create a reuse link list as well, which are a list of now
retired former items which can be recycled without explicit new and
delete operations, but only obj->isActive = true; and
obj->isActive = false; operations.
 
Thank you,
Rick C. Hodgin
Juha Nieminen <nospam@thanks.invalid>: Mar 20 07:37AM

> kushal bhattacharya, you misunderstand the purpose of my posts.
 
Nobody cares about your posts, you lying hypocrite.
 
Your magical incantations aren't real. They aren't going to magically
affect people, no matter how much you believe they do. And it makes
you a hypocrite that even you yourself don't follow your own holy
scripture. So just shut up, hypocrite.
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Mar 20 05:23AM -0700

On Monday, March 20, 2017 at 3:38:06 AM UTC-4, Juha Nieminen wrote:
> Rick C. Hodgin <rick.c.hodgin@gmail.com> wrote:
> > kushal bhattacharya, you misunderstand the purpose of my posts.
 
> Nobody cares about your posts, you lying hypocrite.
 
I've asked you before: How am I a hypocrite?
 
> affect people, no matter how much you believe they do. And it makes
> you a hypocrite that even you yourself don't follow your own holy
> scripture. So just shut up, hypocrite.
 
I agree with you that magic doesn't work. That's why there is no
magic to it, Juha. It's a spirit ... His Holy Spirit. It's not
flesh. It's not magic. It's the third part of our being, the one
that we lost when original sin entered the world. Jesus takes our
sin away, which restores that lost part. It is from within that
restoration that we are able to follow after God and understand
those things He has for us.
 
Thank you,
Rick C. Hodgin
Andrey Karpov <karpov2007@gmail.com>: Mar 20 05:19AM -0700

In my previous article I wrote (https://www.viva64.com/en/b/0471/) that I don't like the approach of evaluating the efficiency of static analyzers with the help of synthetic tests. In that article, I give the example of a code fragment that the analyzer treats as a special case, and deliberately doesn't issue a warning for. To be honest, I didn't expect such an overflow of comments regarding the fact that an analyzer may not issue warnings because of the mechanisms of false positive elimination. In general the topic of battling against false positives is such a huge part of any static analyzer that it's really not clear what we can discuss here; but still, let's talk about it. Such mechanisms exist not only in our analyzer but also in another analyzers/compilers. Nevertheless, if this topic brought about so much discussion, I think it's worth talking about, and so I wrote this explanatory article: https://www.viva64.com/en/b/0488/
just me <invalid@invalid.org>: Mar 20 11:23AM +0100

On Sat, 18 Mar 2017 21:19:31 -0400
> completly stupid, because implementing and managing larger projects
> is the job of SOFTWARE ENGINEERS, this is why i think she is stupid !
 
> So i am not a liar, because i am an experienced programmer too.
 
yes you ARE a liar, as you promised yesterday not to post in this forum anymore.
 
Bonita Montero <Bonita.Montero@gmail.com>: Mar 20 11:31AM +0100

Please handle the problems with your self-worth by consulting
a headshrinker.
 
--
http://facebook.com/bonita.montero/
Juha Nieminen <nospam@thanks.invalid>: Mar 20 07:44AM

> ... until he stops spamming this newsgroup with his bullshit religious posts.
 
He will never stop, so it doesn't make any difference.
 
Just call him out on his hypocrisy.
"Chris M. Thomasson" <invalid@invalid.invalid>: Mar 19 07:30PM -0700

On 3/9/2017 1:02 PM, Chris M. Thomasson wrote:
> }
> }
> ____________________________________
[...]
 
 
> lock();
> return;
> _______________________________________
 
 
Think of the call to (try_something_else()) as trying to acquire work
from another queue... It can process 42 items before it falls back to
actually performing a blocking all-in wait, call to lock...
 
Any thoughts?
"Rick C. Hodgin" <rick.c.hodgin@gmail.com>: Mar 19 05:13PM -0700


> I have seen your photo on internet, and you are still a young female, and you are still childish, because you don't know about survival.
 
> Thank you,
> Amine Moulay Ramdane.
 
Amine,
 
You should learn to let things go. Harboring anger and hatred the way
you're doing toward Bonita ... it's only going to eat you away piece
by piece from the inside.
 
It's okay to be wrong. It's also okay to be right even if others do
not believe you are right. You must be content with yourself, and
stable enough in your own self assessments to not need the praise and
approval of others. If you're right, you're right, and nobody else
will be able to ultimately say anything against you even if they try.
 
But if you're wrong, you must be strong enough to accept that fact,
learn the new thing, offer any apologies, and then move forward within
the new knowledge.
 
By your many posts here and on other forums, you're failing in all of
these areas today. It's costing you every last ounce of credibility
you may have had, and you're now on to the point of actually making
people angry. It is completely counter-productive to anything about
your cause. I urge you to change paths, Amine. It would be in your
best interests to do so right now.
 
Thank you,
Rick C. Hodgin
"Chris M. Thomasson" <invalid@invalid.invalid>: Mar 19 04:34PM -0700

On 3/19/2017 12:58 PM, Jerry Stuckle wrote:
>>> http://facebook.com/bonita.montero/
 
>> he is just plain idiot
 
> What do you have against plain idiots to insult them like that?
 
Wow! amine seems like a hyper-excited entity. Quick to lash out. Minima
of a function of "acknowledgement/learning" deeply explored.
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: