|
Boost : |
Subject: Re: [boost] Synapse library review starts today December 2
From: Klemens Morgenstern (klemens.morgenstern_at_[hidden])
Date: 2016-12-04 16:32:53
Am 04.12.2016 um 22:05 schrieb Emil Dotchevski:
> On Sun, Dec 4, 2016 at 4:09 AM, Klemens Morgenstern <
> klemens.morgenstern_at_[hidden]> wrote:
>
>>
>> Am 04.12.2016 um 11:45 schrieb Emil Dotchevski:
>>
>>> On Sat, Dec 3, 2016 at 10:07 AM, Klemens Morgenstern <
>>> klemens.morgenstern_at_[hidden]> wrote:
>>>
>>> Am 03.12.2016 um 18:56 schrieb Peter Dimov:
>>>> Klemens Morgenstern wrote:
>>>>> But really having a void* as part of a public interface would've given
>>>>>
>>>>>> you a no, even if everything else was perfect with this library.
>>>>>>
>>>>>> This objection of yours doesn't make much sense to me. What problem are
>>>>> you trying to prevent? Objects of different types don't typically share
>>>>> the
>>>>> same address, so type safety can hardly be violated. Well, I suppose you
>>>>> could use the wrong member of a union by mistake.
>>>>>
>>>>> Or a boost.variant.
>>> In Synapse, emitters are identified by their address, so union members
>>> represent the same emitter, by definition. Even if somehow the type of the
>>> emitter participated in its identifier, you'd have the same problem in
>>> case
>>> of union members of the same type.
>>>
>>>
>>> Or you could just by coincidence have a new object at the address of an
>>>> old one, long after it has been deleted - which is actually easy to do,
>>>> since you can put the objects that emit on the stack.
>>>>
>>> Use shared_ptr with null deleter and weak_ptr to avoid that. See "Emitter
>>> lifetime safety" in http://zajo.github.io/boost-synapse/Tutorial.html.
>>>
>> Alright, tell me if this code works properly.
>>
>> class
>> my_button
>> {
>> ....
>> void
>> emit_button_clicked()
>> {
>> synapse::emit<button_clicked>(this);
>> }
>> };
>>
>>
>>
>> //...
>> boost::shared_ptr<synapse::connection> c;
>> {
>> my_button b;
>> c=synapse::connect<button_clicked>(&b,f);
>> synapse::emit<button_clicked>(&b); //should work properly
>> }
>> {
>> int i = 42;
>> synapse::emit<button_clicked>(&i); //yeah, not a good idea
>> }
>>
> I'm assuming that you're not saying that it's a problem because "i" and "b"
> are different objects but because "i" is not a "my_button", and there is a
> chance that somehow it could be accessed as a "my_button", which would be
> undefined. I don't think this could happen through connect/emit, not
> without using an explicit cast.
>
> On the other hand, the ability to erase the type of the emitter is often
> useful, for example to eliminate physical coupling between different parts
> of a program. In fact it is exactly as useful (and exactly as dangerous) as
> when done with pointers, and being able to erase (or even cast) the static
> type of a pointer is sometimes important.
>
> Emil
>
In my example, isn't that precisely what would happen - without a cast?
Of course this is a rare case, but one that has to be taken into
account, I think.
Of course you're right, that type erasure can be useful, but for all
pointers you have explicit conversions, except if you convert to void*.
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk