Sunday, December 21, 2014

Digest for comp.lang.c++@googlegroups.com - 24 updates in 3 topics

Christopher Pisz <nospam@notanaddress.com>: Dec 21 11:53AM -0600

On 12/20/2014 4:17 PM, Chris Vine wrote:
> cancellation is in use, but that is a side issue. I think you program
> for windows, which does not have meaningful (that is,
> deferred/blockable) cancellation.
 
What is the alternative to Fibble's code?
 
It is often that I have some base class that I want to derive from and
concretely specify the work in the derived class.
 
For example I might have one class that consumes XML documents from
threadsafe queue, while another consumes JSON. I want both to run in
parallel to my main program and prepare "configuration" structs that I
can grab from them.
 
Naturally I would want to have a base class, a XML consumer class and a
JSON consumer class.
 
Are you saying that each derived class would bind its own parsing method
to a thread object contained in the base?
Mr Flibble <flibble@i42.co.uk>: Dec 21 06:04PM

On 20/12/2014 22:17, Chris Vine wrote:
 
>> That is like saying "It is horrible 1990's over-OO design to use
>> virtual functions." which is of course nonsense.
 
> It is of course nonsense. Which is why that is not what I said.
 
It is equivalent to what you said in this case.
 
> rather than force derivation just to achieve the same end. (And we are
> talking about C++11 here, as the OP's criticisms of std::thread formed
> the subject of the originating post.)
 
It is not over design at all mate; basically you are clueless.
 
> cancellation is in use, but that is a side issue. I think you program
> for windows, which does not have meaningful (that is,
> deferred/blockable) cancellation.
 
As it happens, mate, there is nothing wrong with my code.
 
/Flibble
"Chris M. Thomasson" <no@spam.invalid>: Dec 21 11:03AM -0800

> threads, and it seems very braindead. I mean third party libraries have
> been giving us working threading for years, and "THAT"was all they came
> up with for the standard?
 
[...]
 
AFAICT, it is not brain-dead. The only little quibble I have is that C++11
gives us a way to wait on lock-based algorithms via condvar, however
there is no stock method to wait on conditions generated by lock/wait-free
algorithms. Luckily, one can build something that works by using what's
there.
 
This can all be done portably now. FWIW, take a look at the following topic:
 
https://groups.google.com/forum/?hl=en#!topic/lock-free/X3fuuXknQF0
 
and:
 
https://groups.google.com/d/topic/lock-free/acjQ3-89abE/discussion
 
 
All of the algorithms there can be portably implemented in C++11.
 
that is VERY nice!
 
:^D
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 21 08:07PM

On Sun, 21 Dec 2014 18:04:35 +0000
> It is not over design at all mate; basically you are clueless.
 
So you have a program which happens to have, say, 100 functions which
might be executed in their own threads at some point during execution
of the program. You want to have the class representing a thread to
have a separate start method, so you cannot use std::thread just by
itself. One approach is to have a single concrete thread class, where
each function/callable object in question is passed at object
construction time and stored in a std::function or similar object, which
is a data member of the class, and which is executed when start is
called.
 
Another approach is to have a virtual run method of a virtual base
thread class and force the programmer to write 100 derived classes,
each with their own version of the run method representing the function
in question to be executed by it (that is what your virtual 'task'
method did).
 
The first approach provides run time binding to a polymorphic function
object. The second provides compile time binding in the class
definition but with run time virtual method selection. I very much
prefer the first.
 
> As it happens, mate, there is nothing wrong with my code.
 
To adopt your favourite response, you're talking shite, mate. With
the BSDs and linux (and possibly commercial unixes), forced stack
unwinding on cancellation would cause the program to terminate when it
hits your catch-all clause. As I said, that is not a problem in
windows (your platform) because it does not have meaningful/usable
cancellation.
 
Chris
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 21 08:32PM

On Sun, 21 Dec 2014 11:53:43 -0600
> a JSON consumer class.
 
> Are you saying that each derived class would bind its own parsing
> method to a thread object contained in the base?
 
No, I am saying don't have a derived class at all. Each object of the
concrete class would have a parsing method (or any other function to be
run in a thread) bound to it at run time.
 
poco threads now have a sort of hybrid arrangement. You can now either
pass start a callable object, or you can pass it a runnable object
which has implemented a virtual run method. I don't see the point of
that.
 
Chris
Ian Collins <ian-news@hotmail.com>: Dec 22 09:42AM +1300

Chris Vine wrote:
> pass start a callable object, or you can pass it a runnable object
> which has implemented a virtual run method. I don't see the point of
> that.
 
Maybe it's because people are comfortable with that design?
 
--
Ian Collins
Mr Flibble <flibble@i42.co.uk>: Dec 21 08:49PM

On 21/12/2014 20:07, Chris Vine wrote:
> hits your catch-all clause. As I said, that is not a problem in
> windows (your platform) because it does not have meaningful/usable
> cancellation.
 
You are still talking shite mate. My catch-all rethrows. If I wanted to
support thread cancellation I would throw a cancellation object; pthread
stack cancellation is UB as far as C++ is concerned so is off-topic.
 
/Flibble
Ian Collins <ian-news@hotmail.com>: Dec 22 10:09AM +1300

Mr Flibble wrote:
 
> You are still talking shite mate. My catch-all rethrows. If I wanted to
> support thread cancellation I would throw a cancellation object; pthread
> stack cancellation is UB as far as C++ is concerned so is off-topic.
 
How would you "throw a cancellation object"? That appears to be the
opposite of thread cancellation where the operation is initiated from
another thread.
 
--
Ian Collins
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 21 09:47PM

On Sun, 21 Dec 2014 20:49:08 +0000
> to support thread cancellation I would throw a cancellation object;
> pthread stack cancellation is UB as far as C++ is concerned so is
> off-topic.
 
On looking at your code again I see you are right on the rethrow point.
The problem you have with your code is not program termination, but that
cancellation would be logged as if it were an exception error, which is
an intractable problem with your design because in common
implementations cancellation objects have no type or name. All you can
do is rethrow them with a generic throw.
 
However you are still wrong about your 1990's-style 'runnable' virtual
base class, mate (IMO). In any event, C++11 has gone for the more
usable std::function concrete class for that kind of polymorphism.
 
Chris
Mr Flibble <flibble@i42.co.uk>: Dec 21 10:25PM

On 21/12/2014 21:09, Ian Collins wrote:
 
> How would you "throw a cancellation object"? That appears to be the
> opposite of thread cancellation where the operation is initiated from
> another thread.
 
In my designs threads cancel themselves or can be told to cancel themselves.
 
/Flibble
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 21 10:25PM

On Mon, 22 Dec 2014 10:09:08 +1300
 
> How would you "throw a cancellation object"? That appears to be the
> opposite of thread cancellation where the operation is initiated from
> another thread.
 
You cannot do it portably across platforms (and Flibble may well just be
confused), but you can sort-of do what he suggests on POSIX platforms.
The system calls which represent cancellation points are by and large
the same as those that are interruptible by a signal. So you can set a
flag, unblock system calls in the target thread by sending a signal with
pthread_kill(), and get the target thread to inspect its flags on EINTR
and commit suicide by throwing its own exception object which is caught
in the entry-point callable.
 
I don't think this can be done on Flibble's platform though. And if
you cannot interrupt blocking system calls then it is pointless.
 
Chris
Mr Flibble <flibble@i42.co.uk>: Dec 21 10:28PM

On 21/12/2014 21:47, Chris Vine wrote:
> an intractable problem with your design because in common
> implementations cancellation objects have no type or name. All you can
> do is rethrow them with a generic throw.
 
In my designs threads cancel themselves by throwing a custom thread
cancellation object. Again pthread cancel is off-topic in this ng.
 
 
 
> However you are still wrong about your 1990's-style 'runnable' virtual
> base class, mate (IMO). In any event, C++11 has gone for the more
> usable std::function concrete class for that kind of polymorphism.
 
You can keep repeating the same shite over and over again but it will
remain shite. There is *nothing* wrong with the template method pattern
and there is nothing wrong having a class that represents a thread of
execution that performs a specific task.
 
 
> Chris
 
/Flibble
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 21 10:30PM

On Sun, 21 Dec 2014 22:28:26 +0000
> In my designs threads cancel themselves by throwing a custom thread
> cancellation object. Again pthread cancel is off-topic in this ng.
 
You can't do that effectively on windows, your platform, I believe.
 
> remain shite. There is *nothing* wrong with the template method
> pattern and there is nothing wrong having a class that represents a
> thread of execution that performs a specific task.
 
You're talking shite mate. When you wrote your code mobile telephones
probably weighed 5 pounds. You need to get with the beat.
 
Chris
Mr Flibble <flibble@i42.co.uk>: Dec 21 10:36PM

On 21/12/2014 22:30, Chris Vine wrote:
>> In my designs threads cancel themselves by throwing a custom thread
>> cancellation object. Again pthread cancel is off-topic in this ng.
 
> You can't do that effectively on windows, your platform, I believe.
 
That's amazing; I cannot explain how I am able to do it then.
 
>> thread of execution that performs a specific task.
 
> You're talking shite mate. When you wrote your code mobile telephones
> probably weighed 5 pounds. You need to get with the beat.
 
Funny but I used to work in the mobile phone industry and I was part of
the team that invented the smartphone.
 
Don't try to troll me mate as you are punching well above your weight.
 
 
> Chris
 
/Flibble
"Chris M. Thomasson" <no@spam.invalid>: Dec 21 02:43PM -0800

> >> cancellation object. Again pthread cancel is off-topic in this ng.
 
> > You can't do that effectively on windows, your platform, I believe.
 
 
> That's amazing; I cannot explain how I am able to do it then.
 
IIRC, pthread-win32 has deferred cancellation, and asynchronous
cancel is a kernel hack requiring a special driver be installed or
something:
 
https://www.sourceware.org/pthreads-win32
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 21 10:44PM

On Sun, 21 Dec 2014 22:36:58 +0000
> > On Sun, 21 Dec 2014 22:28:26 +0000
> > You can't do that effectively on windows, your platform, I believe.
 
> That's amazing; I cannot explain how I am able to do it then.
 
Go ahead and explain. I am interested in any mainstream platform.
 
[snip]
 
> Funny but I used to work in the mobile phone industry and I was part
> of the team that invented the smartphone.
 
> Don't try to troll me mate as you are punching well above your weight.
 
Don't like your own shite shovelling then? Oh dear.
 
Chris
Mr Flibble <flibble@i42.co.uk>: Dec 21 10:53PM

On 21/12/2014 22:44, Chris Vine wrote:
>>> You can't do that effectively on windows, your platform, I believe.
 
>> That's amazing; I cannot explain how I am able to do it then.
 
> Go ahead and explain. I am interested in any mainstream platform.
 
If you don't make blocking calls thread cancellation is trivial mate.
In my designs I don't make blocking calls. My thread class can be
cancelled by another thread quite easily as all that happens is a flag
is set and the thread cancels itself by throwing a cancellation object.
 
>> of the team that invented the smartphone.
 
>> Don't try to troll me mate as you are punching well above your weight.
 
> Don't like your own shite shovelling then? Oh dear.
 
What shite mate? I was part of the team that developed the first
smartphone: the Ericsson R380. It didn't weigh 5 pounds.
 
/Flibble
Chris Vine <chris@cvine--nospam--.freeserve.co.uk>: Dec 21 11:07PM

On Sun, 21 Dec 2014 22:53:10 +0000
> cancelled by another thread quite easily as all that happens is a
> flag is set and the thread cancels itself by throwing a cancellation
> object.
 
That's hopeless. One of the reasons you often want to start a thread
is so that you can make blocking calls, so you can program serially
rather than with asynchronous callbacks. In POSIX, it is the blocking
calls which represent cancellation points (other than
pthread_testcancel()).
 
Incidentally, that is the reason why thread cancellation will probably
never become part of the C++ standard, and why boost interruptible
threads never got any further. To be effective they depend on the
behaviour of blocking system calls, which is platform dependent.
 
Chris
Mr Flibble <flibble@i42.co.uk>: Dec 21 11:21PM

On 21/12/2014 23:07, Chris Vine wrote:
> rather than with asynchronous callbacks. In POSIX, it is the blocking
> calls which represent cancellation points (other than
> pthread_testcancel()).
 
Not hopeless at all. Yes one reason to create a thread is if you *have*
to make multiple simultaneous blocking calls however I maintain that you
don't have to make blocking calls if you design things properly (and are
not stuck with some legacy code). You obviously don't have the
experience to think about how to design things in a non-simplistic
(blocking) way. Any monkey can write code that blocks.
 
> never become part of the C++ standard, and why boost interruptible
> threads never got any further. To be effective they depend on the
> behaviour of blocking system calls, which is platform dependent.
 
The first sensible thing you've said but alas mostly irrelevent to me as
I am able to write non-blocking code; shame you can't.
 
/Flibble
Paavo Helde <myfirstname@osa.pri.ee>: Dec 21 02:48AM -0600

ram@zedat.fu-berlin.de (Stefan Ram) wrote in news:syntax-20141221015603
@ram.dialup.fu-berlin.de:
 
These questions seem to be about the terminology used in the standard;
trying to answer as best as I can, but IANAL.
 
>::std::string( 3, 'c' )
> int()
 
> called?
 
Explicit type conversion (5.2.3)
 
> Is this called a function-style cast?
> (But then, which value is cast in »int()«?).
 
Here, value is produced by value-initializing an object of type int
(5.2.3). For an int, this means the value is zero-initialized (8.5/8).
So, the answer is 0.
 
 
> In the first two cases, it seems to create a new object.
> It seems to use direct initialization.
 
Yes (8.5/16).
 
> But would one call
> »int()« a case of direct-initialization too?

I think not; this is value-initialization which I think is distinct from
direct-initialization.
 
> are syntactically two possible usages: »int()« with empty
> parentheses and »int(x)« with a scalar value »x«. Is this
> correct?
 
Two possible usages of what?
 
With int(x), x can be any type which is convertible to int. For example,
an object of a class which declares 'operator int' conversion.
 
> the declaration T x( ... ) with the same arguments »...«
> is possible, and then the value of T( ... ) is the value
> x would have directly after the declaration. Is this correct?
 
Basically, yes (5.2.3). For a single argument, the standard says the type
conversion expression is equivalent to the corresponding cast expression
(5.4). Maybe this allows a bit more?
 
> still write
 
> T x = T();
> . So this would be a use-case for T()?
 
Yes, sure.
 
> copied into x, when it is destroyed as the last step
> in the evaluation of »T()«, which would be just
> /before/ the copying is to take place.)
 
Obviously the value of the temporary is used for initializing the
declared object, but not sure about the exact terminology.
 
> sense to call it an »instance(-creating) expression«,
> because we hardly feel that »3, 'c'« is »cast« to
> a string in this case?
 
It's called "explicit type conversion".
 
hth
Paavo
Paavo Helde <myfirstname@osa.pri.ee>: Dec 21 08:29AM -0600

ram@zedat.fu-berlin.de (Stefan Ram) wrote in news:int-20141221140608
> It can be followed either by »)« or by an expression.
 
> (And there are no other possibilities, for example, one
> can never have two arguments as in »int( 2, "a" )«.)
 
The sequence of tokens 'int' and '(' can appear in other contexts as well,
e.g.
 
int(*x)() = nullptr;
 
struct A {
operator int() {return 42;}
};
"Öö Tiib" <ootiib@hot.ee>: Dec 21 11:08AM -0800

On Sunday, 21 December 2014 03:27:00 UTC+2, Stefan Ram wrote:
> int()
 
> called? Is this called a function-style cast?
> (But then, which value is cast in »int()«?).
 
I don't think they have some special name. Expression.
More specifically postfix expression. The C++11
'T{}' and 'T{something}' are also from that pack.
[expr.post]:
 
... some stuff ...
simple-type-specifier ( expression-listopt )
typename-specifier ( expression-listopt )
simple-type-specifier braced-init-list
typename-specifier braced-init-list
... some more stuff ...
 
Why there must be some special name?
ram@zedat.fu-berlin.de (Stefan Ram): Dec 21 01:26AM

#include <iostream>
#include <ostream>
#include <string>
 
int main()
{ ::std::cout << ::std::string( "abc" )<<
::std::string( 3, 'c' )<< int() << '\n'; }
 
How is the syntax of expressions like
 
::std::string( "abc" )
::std::string( 3, 'c' )
int()
 
called? Is this called a function-style cast?
(But then, which value is cast in »int()«?).
 
In the first two cases, it seems to create a new object.
It seems to use direct initialization. But would one call
»int()« a case of direct-initialization too?
 
It seems that in the case of the arithmetic type »int«, there
are syntactically two possible usages: »int()« with empty
parentheses and »int(x)« with a scalar value »x«. Is this
correct?
 
It seems that in the case of a class, the possible
arguments are determined by the constructors of the
class and that - would it not be for the most-vexing
parse - an expression T( ... ) is possible whenever
the declaration T x( ... ) with the same arguments »...«
is possible, and then the value of T( ... ) is the value
x would have directly after the declaration. Is this correct?
 
And, when one cannot write
 
T x();
 
to define x, because this declares a function x, one can
still write
 
T x = T();
 
. So this would be a use-case for T()?
 
I assume T() is a temporary, that exists only during
the evaluation of its full-expression, but in the case
of T x = T(); its value is copied into another object,
so the value survives. (Actually, in »T x = T();«,
the »T()« is the full expression, so the value should
be destroyed at the end of its evaluation:
 
»Temporary objects are destroyed as the last step in
evaluating the full-expression (1.9) that (lexically)
contains the point where they were created.«
 
This make me wonder how the value of »T()« can be
copied into x, when it is destroyed as the last step
in the evaluation of »T()«, which would be just
/before/ the copying is to take place.)
 
Even if »::std::string( 3, 'c' )« is called »a
function-style cast« (I'm not sure), it might make more
sense to call it an »instance(-creating) expression«,
because we hardly feel that »3, 'c'« is »cast« to
a string in this case?
ram@zedat.fu-berlin.de (Stefan Ram): Dec 21 01:08PM

>>parentheses and »int(x)« with a scalar value »x«. Is this
>>correct?
>Two possible usages of what?
 
Two possible usages of »int(«:
It can be followed either by »)« or by an expression.
 
(And there are no other possibilities, for example, one
can never have two arguments as in »int( 2, "a" )«.)
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: