From: Mathias Gaunard on
On Aug 5, 10:14 am, w...(a)seed.net.tw wrote:

> At this stage of development, only manpage is available.
> There are .info .html.pdf ...., this could be just matters of taste,
> if you're not talking about the contents.

I mean it's a pretty simple reference, with minimal comments, that's
not even in a easily exploitable cross-referenced format.

I wouldn't call that particularly good documentation, but you claimed
this as a good point for your library.


> http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d92...

That's some extremely verbose way of writing a trivial thing.
Yes, functions need to translate errors or exceptions that happen in
the functions they call, but you don't have to do it on a per-function
basis, you can do it globally. No need to duplicate things either,
only deal with the special cases.


> Functions report exit status either by returning WyRet or by
> throwing
> class of Reply family.
>
> WyRet -- as return type
>
> Use WY_RETURN(em) to return reply with SLI. or return(Ok)
> to
> indicate success.
>
> WyRet -- as base class of the throw type
> Function not appropriate to return WyRet should throw Reply
> (inherited from WyRet, adding no data member). For example
> constructor/destructor and operator overloads... Class
> Reply is
> defined not to cross the function call, which need
> programming
> supports.
> ('Exception' is a system-wise consideration. see C++
> PROGRAMMING
> LANGUAGE, BJARNE STROUSTRUP, 3rd, p383)
>
> Any function detects inconsistent data should not return
> nor
> throw without considering how other functions will react
> to the condition (recover procedure could be entered),
> otherwise
> go to std::terminate(). (Information can not be proved
> 'broken', and
> the propagation can not be free from 'noise')
>
> The exact class WyRet to throw is reserved to mean 'stack
> unwinding
> to exit'. Throwing mechanism of C++ language is regarded
> merely part
> of the function control flow, intent is much less relevant
> in this
> respect. (See [THE ANNOTATED C++ REFERENCE MANUAL,
> ELLIS,STROUSTRUP,
> 15.1, p353-p355] [The Design and Evolution of C++, BJARNE
> STROUSTRUP
> , 16.6, p390] [C++ Standard 15.3.9])
>
> Use WY_THROW(...) to throw class with SLI
> WY_RETURN(...) to return WyRet with SLI
> WY_HERE(...) to set SLI at the location this macro appeared
>

So basically you use return codes except when you have to use
exceptions?
That's pretty bad design.

The distinction between an error code and an exception should be in
semantics, not in whether it's a function or an overloaded operator.


> -- Class member rules
>
> Let T denote a given class of this library. The following member
> names
> and associated functionalities are defined.
>
> T() Default constructor. The object thus construted is
> referred
> to as in default state and so the default object.
>
> Postcondition of throw: object does not exist.
>
> Note: If object can mean 'no real contents', or be
> unbound state
> etc., the default object is better thus designed,
> at least
> to be safely destructable.
>
> reset(...)
> Reconstruct the object to the state as constructed.
> If reset(..) defined, there exists the argument
> corresponding
> constructor (reset() usually exists)
>
> For reset() (no argument), object return state (and
> Reply) is
> always default.
>
> ~T Destruct and discard object
>
> Postcondition: object does not exist
>
> .......................
> swap(..)
> Exchange object state of *this and the argument indicated
> object.
>
> Take 'a.swap(b)' (commutative) for instance, the state of
> a is set
> to the state of b. The previous state of a becomes the
> state of b.
> The same applies for b
>
> Note: No construct and destruct semantics involved
>
> Reply
> Class specific throw class inherited from WyRet.
> ...........
> -- No room should be left for lower-level implement (design).
> (This rule is borrowed from "The Design and Evolution of C++"
> [BJARNE STROUSTRUP, 4.5, p120])
>
> -----------------------------------------------------------------------
> The reset rule could be applied to vast amount of classes, reducing
> analytic effort and complexity between class members.

So basically, your rules are that all objects should be default-
constructible, even if that means adding a new state "has no real
contents".
This is quite silly in my opinion; if the object has no real contents,
it's not usable, and trying to use it in that condition will fail. If
you didn't require default constructors, you could statically
guarantee that objects are always in a usable state, and thus avoid
those potential failures, making the code safer and easier.

But then quite a few people seem to think always having default
constructability is a good idea. Iterators are designed that way for
example.


> > The only way to do thread cancellation right, in C++, is to *not use*
> > pthread cancellation though.
>
> Rationale?

Because just "stopping" code can lead to all sorts of leaks, and can
put the application in a completely unstable state at some operations
need to not be interrupted to guarantee data integrity.
Cancellation should be done cooperatively.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Mathias Gaunard on
On Aug 5, 3:11 am, n...(a)gosset.csi.cam.ac.uk (Nick Maclaren) wrote:

> Er, no. While using pthread cancellation is definitely wrong, there
> is NO way to do it correctly in a language like C++ - that is the
> fundamental problem.

Sure there is. Check from time to time, in particular at all "wait"
synchronization primitives, if you're being requested to stop. If you
are, throw an exception.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Nick Maclaren on
In article <226321bc-f57a-4c19-a517-98424519ad03(a)14g2000yqa.googlegroups.com>,
Mathias Gaunard <loufoque(a)gmail.com> wrote:
>
>> Er, no. While using pthread cancellation is definitely wrong, there
>> is NO way to do it correctly in a language like C++ - that is the
>> fundamental problem.
>
>Sure there is. Check from time to time, in particular at all "wait"
>synchronization primitives, if you're being requested to stop. If you
>are, throw an exception.

Sigh. Do you REALLY not know why that is not a correct way to
handle asynchronous exceptions (including cancellation) in general
code?

If you don't, think I/O - and, in particular, input from a stream
that may be connected to an interactive device or socket. There
are lots of other, similar problems.

A more subtle one is implied by your 'solution'. Should you check
before or after the 'wait'? The answer is both, but that is not
enough - you need to replace the wait by a spin loop of short waits.
But do you know why THAT one is incorrect, too? I shall leave it
as an exercise :-)


Regards,
Nick Maclaren.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Mathias Gaunard on
On Aug 6, 4:33 am, n...(a)gosset.csi.cam.ac.uk (Nick Maclaren) wrote:

> Sigh. Do you REALLY not know why that is not a correct way to
> handle asynchronous exceptions (including cancellation) in general
> code?

You could ignore requests for cancellation, but that's your fault, not
that of the design.
Likewise, you can ignore requests for interruption/termination by
defining your own handler for SIGINT and SIGTERM.


> If you don't, think I/O - and, in particular, input from a stream
> that may be connected to an interactive device or socket. There
> are lots of other, similar problems.

I don't see any particular problem with that.
Any expensive operation should be buffered, and you can check if
you're being requested to cancel at each buffering interval.


> A more subtle one is implied by your 'solution'. Should you check
> before or after the 'wait'?

Seems like you misunderstood.
The wait does the check automatically. It's one of the necessary
interruption points provided by the threading support library. It
couldn't work otherwise, as you'd be stuck waiting with no way to
cancel the thread...

See the design of Boost.Threads and the former proposed standard
threads.



--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: wij on
On 8月6日, 上午2時52分, Mathias Gaunard <loufo...(a)gmail.com> wrote:
> On Aug 5, 10:14 am, w...(a)seed.net.tw wrote:
>
>> At this stage of development, only manpage is available.
>> There are .info .html.pdf ...., this could be just matters of taste,
>> if you're not talking about the contents.
>
> I mean it's a pretty simple reference, with minimal comments, that's
> not even in a easily exploitable cross-referenced format.
>
> I wouldn't call that particularly good documentation, but you claimed
> this as a good point for your library.
>
This library tries to minimize introduction of new concept by
minimize the use of names. This can be reflected in the documents.
If users feels no need for those textural information, it is a
success of this library. You can find much fewer names than find in
other libraries. The number of names is a measure of quality, IMO.

I'm not quite sure "what exploitable cross-referenced format" means?
anchor,links?
>> http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d92...
>
> That's some extremely verbose way of writing a trivial thing.
> Yes, functions need to translate errors or exceptions that happen in
> the functions they call, but you don't have to do it on a per-function
> basis, you can do it globally. No need to duplicate things either,
> only deal with the special cases.
>
Library functions can't report errors globally or collectively.
User's codes can, though.

The idea of error checking comes to my mind. Though, error checking
is (even extremely) tedious and ugly, it is not trivial. Think of
those time spend on debugging, maintaining. Over 90% of those time,
including associated money, credit,damages,people interactions..
... can be saved just by adding the seemingly trivial error checking
codes, Checking collectively is possible, but can't talk about it in
general.
>
>
>> Functions report exit status either by returning WyRet or by
>> throwing
>> class of Reply family.
>
>> WyRet -- as return type
>
>> Use WY_RETURN(em) to return reply with SLI. or return(Ok)
>> to
>> indicate success.
>
>> WyRet -- as base class of the throw type
>> Function not appropriate to return WyRet should throw Reply
>> (inherited from WyRet, adding no data member). For example
>> constructor/destructor and operator overloads... Class
>> Reply is
>> defined not to cross the function call, which need
>> programming
>> supports.
>> ('Exception' is a system-wise consideration. see C++
>> PROGRAMMING
>> LANGUAGE, BJARNE STROUSTRUP, 3rd, p383)
>
>> Any function detects inconsistent data should not return
>> nor
>> throw without considering how other functions will react
>> to the condition (recover procedure could be entered),
>> otherwise
>> go to std::terminate(). (Information can not be proved
>> 'broken', and
>> the propagation can not be free from 'noise')
>
>> The exact class WyRet to throw is reserved to mean 'stack
>> unwinding
>> to exit'. Throwing mechanism of C++ language is regarded
>> merely part
>> of the function control flow, intent is much less relevant
>> in this
>> respect. (See [THE ANNOTATED C++ REFERENCE MANUAL,
>> ELLIS,STROUSTRUP,
>> 15.1, p353-p355] [The Design and Evolution of C++, BJARNE
>> STROUSTRUP
>> , 16.6, p390] [C++ Standard 15.3.9])
>
>> Use WY_THROW(...) to throw class with SLI
>> WY_RETURN(...) to return WyRet with SLI
>> WY_HERE(...) to set SLI at the location this macro appeared
>
> So basically you use return codes except when you have to use
> exceptions?
yes.
> That's pretty bad design.
>
> The distinction between an error code and an exception should be in
> semantics, not in whether it's a function or an overloaded operator.
>
It may not be what you though, or are taught.
The basic is that return and throw are not equivalent.
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d92ec2a33f1751fb/0835558fe27a4f9b?lnk=gst&q=throwing+error+is+buggy#0835558fe27a4f9b
>
>
>> -- Class member rules
>
>> Let T denote a given class of this library. The following member
>> names
>> and associated functionalities are defined.
>
>> T() Default constructor. The object thus construted is
>> referred
>> to as in default state and so the default object.
>
>> Postcondition of throw: object does not exist.
>
>> Note: If object can mean 'no real contents', or be
>> unbound state
>> etc., the default object is better thus designed,
>> at least
>> to be safely destructable.
>
>> reset(...)
>> Reconstruct the object to the state as constructed.
>> If reset(..) defined, there exists the argument
>> corresponding
>> constructor (reset() usually exists)
>
>> For reset() (no argument), object return state (and
>> Reply) is
>> always default.
>
>> ~T Destruct and discard object
>
>> Postcondition: object does not exist
>
>> .......................
>> swap(..)
>> Exchange object state of *this and the argument indicated
>> object.
>
>> Take 'a.swap(b)' (commutative) for instance, the state of
>> a is set
>> to the state of b. The previous state of a becomes the
>> state of b.
>> The same applies for b
>
>> Note: No construct and destruct semantics involved
>
>> Reply
>> Class specific throw class inherited from WyRet.
>> ...........
>> -- No room should be left for lower-level implement (design).
>> (This rule is borrowed from "The Design and Evolution of C++"
>> [BJARNE STROUSTRUP, 4.5, p120])
>
>> -----------------------------------------------------------------------
>> The reset rule could be applied to vast amount of classes, reducing
>> analytic effort and complexity between class members.
>
> So basically, your rules are that all objects should be default-
> constructible, even if that means adding a new state "has no real
> contents".
Yes, I suggest defining default constructor as possible. In practice,
some classes don't have default constructor because default state
don't work or would impose unnecessary burden for other function
members, even for other classes. This may be a whole design issue.

In this library, default object involves the consideration how object
can be safely destroyed. Default object can explicitly provide a
proof (or aid) that the object can be safely destroyed.

> This is quite silly in my opinion; if the object has no real contents,
> it's not usable, and trying to use it in that condition will fail.
Default constructor may exists for reasons I know of:
1. there is good natural default state.
2.to avoid constructor failure and the stack unwind.

> If
> you didn't require default constructors, you could statically
> guarantee that objects are always in a usable state, and thus avoid
> those potential failures, making the code safer and easier.
>
Some errors are inevitable, some is introduced, some are from the
stack unwinding, or hardware triggered.
Where you prepare the errors to occur? constructor or access
functions?

Basically I feel you might really talking about the consistency among
class function members. If so, use the reset rule, if not appropriate
, it may clearly reveal your class or concept design problem or the
reset rule itself. In either cases, you know the problem better.

> But then quite a few people seem to think always having default
> constructability is a good idea. Iterators are designed that way for
> example.
>
>>> The only way to do thread cancellation right, in C++, is to *not use*
>>> pthread cancellation though.
>
>> Rationale?
>
> Because just "stopping" code can lead to all sorts of leaks, and can
> put the application in a completely unstable state at some operations
> need to not be interrupted to guarantee data integrity.
> Cancellation should be done cooperatively.
>
> --
> [ Seehttp://www.gotw.ca/resources/clcm.htmfor info about ]
> [ comp.lang.c++.moderated. First time posters: Do this! ]
It actually indicate errors of user's codes not preparing for stack
unwind. I'm sure of this reason, at least on the current NPTL C++
implements,

P.S. boost thread is not equivalent to pthread, I missed the detail.

Regarding the future C++ thread, If thread cancellation is not
supported, it would be harder to add latter without break written
programs. This also imply real-time system is not supported,
non-standard functions are harder to use.
I don't know good or not.
It is foreseeable, by moore's low, 1000-core cpu or equivalent would
appear in 15-20 years, 1-million core cpu would appear in 30-40 years.
Then people may ask why can't free the allocated resource? This is
just imagination.


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]