Wednesday, September 2, 2015

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

SG <s.gesemann@gmail.com>: Sep 02 04:46AM -0700

On Wednesday, August 26, 2015 at 1:05:45 PM UTC+2, jacobnavia wrote:
 
> > https://code.google.com/p/ccl/
 
> > Have fun!
 
> Interesting that none of the C++ heads objects to this :-)
 
It's not like absence of criticism equals approval. FWIW, I looked at
it (years ago?) when you announced this in comp.lang.c (or some place
else). And I don't remember anyone cheering over it. At least I was
left unimpressed by it. Sure, it's probably among the best thigs you
could implement in plain C. But why accept the limitations of C and
work around them when you can have C++?
 
I'm not particularly in love with C++ either. It has many annoying
warts. But for me it's still better than C simply because I can pick
and choose the tools from a larger toolset. When I want templates I
want templates and no macros or a script invoked by make to generate
a piece of C code from some custom template file format by text
substitution.
 
Right now, I'm quite fond of the Rust programming language, actually.
 
Cheers!
sg
Gerhard Wolf <leawolf@gmx.de>: Sep 02 09:46AM +0200

Hi,
 
if have a unexpected result with the C++Builders TByteDynArray class.
Pruefung[STOP] = AB;
seems to pass ABs value by reference because
[1]-value of Pruefung[STOP] switches to 1 after
AB[1] = 1;
The std::string example works as expected.
 
Why that? How can i avoid this?
Is this a C++ feature defined in the TByteDynArray class?
 
----the console output----------------------------------------------
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
00 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15
00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 
0000000000
----the code--------------------------------------------------------
#include <vcl.h>
#include <windows.h>
 
#pragma hdrstop
#pragma argsused
#include <map>
#include <sstream>
#include <tchar.h>
 
#include <iostream>
#include <iomanip>
const int STOP = 9998;
 
std::string printTByteDynArry(TByteDynArray &td) {
std::stringstream ss;
for (int i(0); i < td.get_length(); i++) {
ss << std::setfill('0') << std::setw(2) << i << " ";
}
ss << std::endl;
for (int i(0); i < td.get_length(); i++) {
ss << std::setfill('0') << std::setw(2) << std::hex << (unsigned int)
td[i] << " ";
}
ss << std::endl;
return ss.str();
}
 
int _tmain(int argc, _TCHAR* argv[])
{
typedef std::map<int, TByteDynArray>TBDyArrMap;
TBDyArrMap Pruefung;
TByteDynArray AB;
AB.set_length(16);
 
for (int i(0); i < 15; i++)
AB[i] = 0;
Pruefung[STOP] = AB;
std::cout << printTByteDynArry(Pruefung[STOP]) << std::endl;
AB[1] = 1;
std::cout << printTByteDynArry(Pruefung[STOP]) << std::endl;
 
typedef std::map<int, std::string> StrMAP;
StrMAP test;
std::string tmp = "0000000000";
test[1] = tmp;
tmp = "1111111111";
std::cout << test[1] << std::endl;
 
return 0;
}
Barry Schwarz <schwarzb@dqel.com>: Sep 02 02:39AM -0700

On Wed, 2 Sep 2015 09:46:44 +0200, Gerhard Wolf <leawolf@gmx.de>
wrote:
 
>seems to pass ABs value by reference because
>[1]-value of Pruefung[STOP] switches to 1 after
>AB[1] = 1;
 
What is the actual type that TBytDynArray is an alias for? If
https://gist.github.com/daeltar/90951 is correct, it is a class with
one int member and one int* member. Since the = operator is not
overloaded, assigning one such object to another should result in the
corresponding members of both objects having the same value.
 
If two pointers point to the same memory, changes made by
dereferencing one pointer will show up when dereferencing the other.
 
 
--
Remove del for email
Kalle Olavi Niemitalo <kon@iki.fi>: Sep 02 01:01PM +0300

> seems to pass ABs value by reference because
> [1]-value of Pruefung[STOP] switches to 1 after
> AB[1] = 1;
 
I am not familiar with C++Builder but I looked at its documentation:
 
http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/delphivclwin32/Types_TByteDynArray.html
says it's defined in Delphi as "TByteDynArray = array of Byte;".
That's a Delphi dynamic array type, I think.
 
http://docwiki.embarcadero.com/Libraries/XE8/en/System.DynamicArray
says the DynamicArray template in C++Builder corresponds to the
Delphi dynamic array type, and it is reference counted.
I suppose C++Builder then defines TByteDynArray as a typedef for
DynamicArray<Byte>; I didn't find that explicitly in the
documentation, but perhaps the typedef is in some header file
distributed with C++Builder.
 
> How can i avoid this?
 
There is apparently a Copy method.
http://docwiki.embarcadero.com/Libraries/XE8/en/System.DynamicArray#Assigning.2C_comparing_and_copying_dynamic_arrays
Kalle Olavi Niemitalo <kon@iki.fi>: Sep 02 01:14PM +0300


> What is the actual type that TBytDynArray is an alias for?
 
System::DynamicArray in C++Builder is the same size as a pointer.
http://docwiki.embarcadero.com/RADStudio/XE8/en/64-bit_Windows_Data_Types_Compared_to_32-bit_Windows_Data_Types
 
> If https://gist.github.com/daeltar/90951 is correct, it is a
> class with one int member and one int* member.
 
It is not correct: it does not define a copy assignment operator,
DynamicArray::resize reads past the end of the old array when
resizing to a larger size, and the comparison operators can
return without specifying a value.
Gerhard Wolf <leawolf@gmx.de>: Sep 02 12:46PM +0200

> There is apparently a Copy method.
> http://docwiki.embarcadero.com/Libraries/XE8/en/System.DynamicArray#Assigning.2C_comparing_and_copying_dynamic_arrays
Great! It works, thanks!
Juha Nieminen <nospam@thanks.invalid>: Sep 02 08:11AM


> This shows the education of Mr Nieminen and his attitude towards people
> that do not have the same programming language tastes.
 
> I do not call people names, Mr Nieminen, it is just bad taste.
 
No, you only make patronizing and provocative comments with a smug attitude.
Because that's so much more civilized.
 
--- news://freenews.netfront.net/ - complaints: news@netfront.net ---
SG <s.gesemann@gmail.com>: Sep 02 03:44AM -0700

On Thursday, August 27, 2015 at 11:31:20 PM UTC+2, jacobnavia wrote:
 
> How can I revert to the good old times?
 
> The compiler that compiled this is gcc-4.4.3, and still does.
 
> The new compiler however will not do that even if I specify -std=c++98
 
C++ compilers always have been required to do a proper "two phase
lookup" (at least since its ISO standardization). It just took a
while for C++ compilers to catch up. I'm not sure what the current
status with Microsoft's compiler is. It may still be "too lazy" to
do a two phase lookup and accept a lot of invalid C++ code.
 
If you're interested in turning your code into valid C++ so it will
be accepted by a conforming compiler, please look into how "two phase
lookup" works. You may have to use the keywords "typename" or
"template" or use an explicit "this->" prefix for member access here
and there.
 
Two phase lookup is not all bad. Its purpose is to catch some errors
early before templates are even instantiated. But to be honest, I
find it embarrassing that we have to use additional template and
typename keywords for disambiguation, for example.
 
If you're looking for a book suggestion: I found "C++ Templates: The
Complete Guide" very illuminating.
 
Cheers!
sg
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 02 12:35AM +0100

On Tue, 01 Sep 2015 18:00:31 -0500
> On 9/1/2015 5:34 PM, Chris Vine wrote:
> > On Tue, 01 Sep 2015 14:56:39 -0500
> > Christopher Pisz <nospam@notanaddress.com> wrote:
[snip]
> > you don't want a timeout, use plain std::condition_variable::wait().
 
> That's not the behavior I am seeing. It outputs "tick..." every 10
> seconds, as expected.
 
Then you are outputting the ticks within the while loop. Fine if it is
for debugging purposes, but otherwise at variance with the purpose of
a condition variable. (Your code snippet above contained no code which
printed anything - it just spun on a timeout without any purpose.
More generally, looping on a timeout is also usually pointless,
particularly if the condition is one to end the thread rather than to
do some work. If the condition was one about the availability of work
it would make a bit more sense.)
 
> I want to loop, because the loop is where the task for the thread is
> done. Unless you are implying that the work goes in the lamda..are
> you?
 
If you are doing work in the while loop above then it must surely be
wrong to have gratuitous waits on a condition variable related to
something completely different, namely whether a stop flag is set?
 
> > On your mutex point, you always call
> > std::condition_variable::wait{for|until}() with the mutex locked.
 
> Isn't that what I am doing?
 
Yes. I wasn't arguing that your code is wrong on this point, but you
asked a question and I answered it. I think you may be conflating this
series of posts with your one containing a request for a code review,
which I haven't read.
 
[snip]
 
 
> Only when the broadcast is done? That would be ok, because all they
> are going to do is go and exit. As long as the body of the while loop
> can be executed in more than one thread at a time.
 
You have lost me on while loops (the while loop above which is dependent
on a timeout occurring and does nothing is only executed one thread at a
time because it executes under the mutex, but I rather think you are
talking about something else). I was just explaining how condition
variables work, as I sensed from your question about mutexes that you
weren't clear. Possibly at some point in whatever while loop you have
you need to release the mutex, and acquire it again before looping.
 
Chris
Christopher Pisz <nospam@notanaddress.com>: Sep 01 06:57PM -0500

On 9/1/2015 6:35 PM, Chris Vine wrote:
 
> If you are doing work in the while loop above then it must surely be
> wrong to have gratuitous waits on a condition variable related to
> something completely different, namely whether a stop flag is set?
 
What's the alternative?
 
> weren't clear. Possibly at some point in whatever while loop you have
> you need to release the mutex, and acquire it again before looping.
 
> Chris
 
Ok, let's move this discussion to the post with the full listing and
discuss the full listing. I just wanted to get past the syntax error for
the one line in this OP.
 
Once over there,
Can you please write an example there with the following requirements in
standard C++?
 
1) Create a main thread
2) Have the main thread create a number of child threads with tasks
encapsulated in an object
3) Have the main thread wait on all children to exit before it, itself
exits.
4) Have all children continue to do their tasks every 10 seconds, in a
loop forever, until told to stop from the main thread
5) Have the main thread handle ctrl-c and tell all children to stop in
response.
 
I have no idea how to edit my code given your responses. I am just
further confused.
 
--
I have chosen to troll filter/ignore all subthreads containing the
words: "Rick C. Hodgins", "Flibble", and "Islam"
So, I won't be able to see or respond to any such messages
---
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 02 01:37AM +0100

On Tue, 01 Sep 2015 18:57:01 -0500
> in response.
 
> I have no idea how to edit my code given your responses. I am just
> further confused.
 
Your "Have all children continue to do their tasks every 10 seconds"
seems completely mad. Why on earth have worker threads gratuitously
doing nothing for 10 seconds on every iteration between tasks,
irrespective of whether there is work available. You must surely mean
something else?
 
If that really is what you want then maybe your design might be OK
(subject to my point about mutex locking), but as I say it is so outside
anything I could contemplate as a reasonable design aim that I couldn't
say more. It is sufficiently bizarre that you ought to have explained
this in your request for a code review.
 
If this is some kind of automated machinery controller that does
something (maybe polls machinery) every 10 seconds I doubt you would
need threads at all: the fact that each thread must sleep for 10
seconds for this to work shows that a single thread would be more than
sufficient and threads are the wrong solution. Threads are supposed to
do things, not not do things.
 
Chris
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 02 01:55AM +0100

On Wed, 2 Sep 2015 01:37:01 +0100
Chris Vine <chris@cvine--nospam--.freeserve.co.uk> wrote:
[snip]
> seconds for this to work shows that a single thread would be more than
> sufficient and threads are the wrong solution. Threads are supposed
> to do things, not not do things.
 
I would suggest a standard single-threaded program event loop with a
timer for each piece of machinery. That bit of the code would require
about 5 lines of code, including handling program termination.
 
Chris
"Christopher J. Pisz" <cpisz@austin.rr.com>: Sep 01 09:15PM -0500

On 9/1/2015 7:55 PM, Chris Vine wrote:
> timer for each piece of machinery. That bit of the code would require
> about 5 lines of code, including handling program termination.
 
> Chris
 
I want separate threads so that each will run completely independent of
the other.
 
Often when polling there is some situation where one has a failure and
must retry continuously. On a single thread, that will hold up all the
others.
 
Also, processing of the data can take more than the wait time seconds,
especially since it is coming over unreliable, third party http, so
again, I want each to run independently.
 
I've got a single threaded solution already. I aim to take 90% of it and
plop it on a thread of its own, rather than running multiple clients.
 
I don't see how that is uncommon at all. I've seen the same pattern at
least thirty times in my career, just not with C++11.
"Christopher J. Pisz" <cpisz@austin.rr.com>: Sep 01 09:19PM -0500

On 9/1/2015 9:15 PM, Christopher J. Pisz wrote:
> plop it on a thread of its own, rather than running multiple clients.
 
> I don't see how that is uncommon at all. I've seen the same pattern at
> least thirty times in my career, just not with C++11.
 
Oh, I should mention, I am not polling machinery, or bunches of them.
Something like 10-20 data sources per client.
"Christopher J. Pisz" <cpisz@austin.rr.com>: Sep 02 01:21AM -0500

On 9/1/2015 7:55 PM, Chris Vine wrote:
> timer for each piece of machinery. That bit of the code would require
> about 5 lines of code, including handling program termination.
 
> Chris
 
I do wonder though reading through the condition_variable docs, it
mentions spinning while waiting. If it actually consumes cycles while
doing nothing, it would be better not to, but I don't see any
alternatives in the standard. I'd have to resort to Windows threads.
 
There is no event or other semaphore available, is there?
Ian Collins <ian-news@hotmail.com>: Sep 02 09:40PM +1200

Christopher J. Pisz wrote:
> mentions spinning while waiting. If it actually consumes cycles while
> doing nothing, it would be better not to, but I don't see any
> alternatives in the standard. I'd have to resort to Windows threads.
 
Where does it say that? A thread waiting on a CV blocks until the CV is
signaled, or something else wakes it (a spurious wake-up). This could
consume cycles, but it would be a poor implementation if it did.
 
--
Ian Collins
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 02 11:20AM +0100

On Tue, 01 Sep 2015 21:15:24 -0500
"Christopher J. Pisz" <cpisz@austin.rr.com> wrote:
[snip]
> clients.
 
> I don't see how that is uncommon at all. I've seen the same pattern
> at least thirty times in my career, just not with C++11.
 
OK, if that's your problem area and you are happy with your approach of
a thread per device (and there are not so many devices that you are
going to run into resource problems), so be it. However, although I
haven't looked at the posting which contained your code other than very
cursorily, it looks like you need to deal with the locking, assuming
all threads share the m_stopCV and m_stopMutex objects, because at
present only one thread will run its task at a time. But that is
easily resolved.
 
Your polling will not run at exactly 10 second intervals. It will be
10 seconds plus the time to run the task. If you want the time to run
the task discarded, you would need to use
condition_variable::wait_until() with a separate time_point object for
the thread, which you reset by a further 10 seconds at each firing.
 
Chris
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Sep 02 11:19AM +0100

On Wed, 02 Sep 2015 01:21:36 -0500
> doing nothing, it would be better not to, but I don't see any
> alternatives in the standard. I'd have to resort to Windows threads.
 
> There is no event or other semaphore available, is there?
 
Condition waits don't spin, unless possibly speculatively for a few
nanoseconds, so you don't have a problem on that score: they don't use
up clock cycles.
 
Chris
Gareth Owen <gwowen@gmail.com>: Sep 02 06:53AM +0100


> As Adam never existed Adam's descendants as described in
> the Bible also never existed ergo Jesus Christ never existed.
 
Formal logic is not really a strength of yours is it?
Marcel Mueller <news.5.maazl@spamgourmet.org>: Sep 02 09:17AM +0200

On 01.09.15 23.40, Mr Flibble wrote:
> extern const unsigned char main[] = { 0xEB, 0xFE }; // Machine code!!! \o/
 
Yippee, an infinite loop.
 
Won't work on anything but x86 and won't work for many compilers since
there is no guarantee that variable symbols will ever match function
symbols. The entry point is sometimes named _main internally (or
something else) and so it won't link.
 
So what should be the use of a hack like this?
 
 
Marcel
Gerhard Wolf <leawolf@gmx.de>: Sep 02 07:29AM +0200

Am 01.09.2015 um 22:07 schrieb Christopher Pisz:
 
> I've created a new minimal compilable example of what I want to achieve
> in production code.
at last Logger class header is missing.
"Christopher J. Pisz" <cpisz@austin.rr.com>: Sep 02 01:17AM -0500

On 9/2/2015 12:29 AM, Gerhard Wolf wrote:
 
>> I've created a new minimal compilable example of what I want to achieve
>> in production code.
> at last Logger class header is missing.
 
 
There was a comment in the first appearance of logger.h that says, just
replace it with any old threadsafe output mechanism. I don't want to
include all that irrelevant code, it would just be distracting.
ram@zedat.fu-berlin.de (Stefan Ram): Sep 02 01:08AM

>>member variable is static and non-constant?
>I think the issue is that for non-const static members, the compiler
>needs to know where to place the memory definition (what object module
 
This can be read in 9.4.2.
 
As I understand it, one must define the static data member
with »::« as follows:
 
struct C { static /**/ int n /**/; }; int C::n; /* untested */
 
. When the first »/**/« is »const«, then we are allowed to
add an initializer at the second »/**/« for some kinds of
types. But we are allowed to omit the definition with »::«
only if the member is not odr-used.
 
Nobody wants to learn what »odr-used« means, so everybody
must always include the ::-definition!
Richard Damon <Richard@Damon-Family.org>: Sep 01 08:48PM -0400

On 9/1/15 9:54 AM, Chris Vine wrote:
> causes a system-generated runtime fault.]"
 
> Thanks to him for pointing that out.
 
> Chris
 
Interesting, this is the first place that I know of where
'implementation defined' specifically includes 'runtime fault'
(presumably allowing immediate termination without any stack unwinding
or cleanup). This sort of behavior is normally only the domain of
undefined behavior.
Richard Damon <Richard@Damon-Family.org>: Sep 01 08:44PM -0400

On 9/1/15 5:24 AM, Paul wrote:
> static int x = 3;
> //
 
> };
 
I think the issue is that for non-const static members, the compiler
needs to know where to place the memory definition (what object module
contains the definition). For static const, this isn't an issue, as the
compiler doesn't actually need to create a memory object, it can just
always use the constant.
 
For non-static members, it just knows to add the initialization to all
constructors.
 
Due to templates and inline functions, the compiler needs to have
mechanisms to handle this sort of stuff, but maybe this case predates
those requirements and was never added.
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: