Re: Can a temporary be assigned to itself?

Discussion in 'C++' started by James Kanze, Mar 22, 2013.

  1. James Kanze

    James Kanze Guest

    On Friday, 22 March 2013 09:05:54 UTC, Juha Nieminen wrote:

    > If you are implementing the regular operator=() for a class, you (usually)
    > need to take into account the special case that the same object is being
    > assigned to itself. (If you don't, you may end up deleting the managed
    > resource when you shouldn't.)


    If you need to take the special case of self-assignment into
    account, your operator is probably broken already. Think about
    what might happen if you delete something in the object, and
    then the acquisition of your resource throws. You end up with
    an object with a pointer to a deleted resource.

    --
    James
     
    James Kanze, Mar 22, 2013
    #1
    1. Advertising

  2. James Kanze

    Balog Pal Guest

    On 3/22/2013 2:41 PM, James Kanze wrote:
    > On Friday, 22 March 2013 09:05:54 UTC, Juha Nieminen wrote:
    >
    >> If you are implementing the regular operator=() for a class, you (usually)
    >> need to take into account the special case that the same object is being
    >> assigned to itself. (If you don't, you may end up deleting the managed
    >> resource when you shouldn't.)

    >
    > If you need to take the special case of self-assignment into
    > account, your operator is probably broken already. Think about
    > what might happen if you delete something in the object, and
    > then the acquisition of your resource throws. You end up with
    > an object with a pointer to a deleted resource.


    I heard that claim a lot, and it sounded good, but I never could really
    map it to actual code.

    Taking your example, my code would call Dispose() that will call the
    proper delete and set the pointer to NULL, then we proceed to allocation
    part. Should it fail we're in a proper non-owning state fulfilling the
    basic XG.

    Sure it it possible to do things in improper order or overlook
    something, but that applies to anything in programming. I considered the
    suggested alternatives many times then concluded that the (pretty rare)
    instances I have providing op= are okay with the self-assignment check
    up front and the rest is fine.

    IME most classes will have either default or deleted op=, the rest is
    maybe 1%. And that small population is mostly primitive library carried
    over for decades.

    In the cases I reviewed with broken op= or more general rule-of-three
    related discrepancy the problem was not with self-assigment or its
    strategy but that the actual class should not have t in the first place,
    rather pick up a proper member or base class. Well, it coming back now
    -- the problem was usually with obtaining something in ctor body, and
    leaked due to dtor not called. And fixing that the proper way, using a
    proper controller for the resource made the op= gone for good as bonus
    side effect. :)
     
    Balog Pal, Mar 22, 2013
    #2
    1. Advertising

  3. James Kanze

    Öö Tiib Guest

    On Friday, 22 March 2013 20:46:59 UTC+2, Balog Pal wrote:
    > On 3/22/2013 2:41 PM, James Kanze wrote:
    > > On Friday, 22 March 2013 09:05:54 UTC, Juha Nieminen wrote:
    > >
    > >> If you are implementing the regular operator=() for a class, you (usually)
    > >> need to take into account the special case that the same object is being
    > >> assigned to itself. (If you don't, you may end up deleting the managed
    > >> resource when you shouldn't.)

    > >
    > > If you need to take the special case of self-assignment into
    > > account, your operator is probably broken already. Think about
    > > what might happen if you delete something in the object, and
    > > then the acquisition of your resource throws. You end up with
    > > an object with a pointer to a deleted resource.

    >
    > I heard that claim a lot, and it sounded good, but I never could really
    > map it to actual code.


    Object should remain in sane state if anything throws exceptions
    during assignment. Sole imaginable sane state is "like it was before".

    On my case it seems that achieving that has also achieved that the
    self-assignment checks are not needed anymore.

    [...]

    > IME most classes will have either default or deleted op=, the rest is
    > maybe 1%. And that small population is mostly primitive library carried
    > over for decades.


    Interesting.

    Domains and applications certainly differ. IME most classes are not
    polymorphic. It is efficient to put most such things into vector
    (or deque) or used as direct data members of other non-polymorphic
    classes.

    Lot of non-polymorphic classes may have constant or reference or
    unique_ptr or auto_ptr or boost::scoped_ptr or naked pointer
    non-static members. These classes should be made explicitly copyable
    or movable if one wants them to be in vector or deque or the like.
     
    Öö Tiib, Mar 22, 2013
    #3
  4. James Kanze

    James Kanze Guest

    On Friday, 22 March 2013 18:46:59 UTC, Balog Pal wrote:
    > On 3/22/2013 2:41 PM, James Kanze wrote:
    > > On Friday, 22 March 2013 09:05:54 UTC, Juha Nieminen wrote:


    > >> If you are implementing the regular operator=() for a class, you (usually)
    > >> need to take into account the special case that the same object is being
    > >> assigned to itself. (If you don't, you may end up deleting the managed
    > >> resource when you shouldn't.)


    > > If you need to take the special case of self-assignment into
    > > account, your operator is probably broken already. Think about
    > > what might happen if you delete something in the object, and
    > > then the acquisition of your resource throws. You end up with
    > > an object with a pointer to a deleted resource.


    > I heard that claim a lot, and it sounded good, but I never could really
    > map it to actual code.


    > Taking your example, my code would call Dispose() that will call the
    > proper delete and set the pointer to NULL, then we proceed to allocation
    > part. Should it fail we're in a proper non-owning state fulfilling the
    > basic XG.


    That's doing things the hard way. As a general rule, you should
    construct all of the new values before you start tearing down
    anything.

    --
    James
     
    James Kanze, Mar 22, 2013
    #4
  5. James Kanze

    Balog Pal Guest

    On 3/22/2013 8:52 PM, Öö Tiib wrote:

    > Object should remain in sane state if anything throws exceptions
    > during assignment. Sole imaginable sane state is "like it was before".


    That is strong XG, can be done too at about the same amount of code but
    some increased resource cost at runtime. I don't agree that strong XG is
    the only sane way but that is up to opinion in general -- and detailed
    design at a particular instance, so we should not debate it. :)
    ....
    > Lot of non-polymorphic classes may have constant or reference or
    > unique_ptr or auto_ptr or boost::scoped_ptr or naked pointer
    > non-static members. These classes should be made explicitly copyable
    > or movable if one wants them to be in vector or deque or the like.


    I have a full suite of smart pointers: NC, DC, transfer and shared,
    certainly if I want a copyable object I use a the DC variant over
    anything else. IMO same applies to any resource handler. (btw the said
    pointers are policy-based so it's easy to use them for any kind of
    resource; I recall a few times using fake-copy that was okay for the
    case).

    IME starting to hand-craft an op= is the last resort and is a ticked for
    more easy-to-break maintenance too.
     
    Balog Pal, Mar 22, 2013
    #5
  6. James Kanze

    Balog Pal Guest

    On 3/22/2013 9:11 PM, James Kanze wrote:
    >> Taking your example, my code would call Dispose() that will call the
    >> proper delete and set the pointer to NULL, then we proceed to allocation
    >> part. Should it fail we're in a proper non-owning state fulfilling the
    >> basic XG.

    >
    > That's doing things the hard way. As a general rule, you should
    > construct all of the new values before you start tearing down
    > anything.


    That's also a fair approach if having both new and old around is not
    considered risk for resource overuse.

    IMO that general rule applies to complex situations, mostly in the
    application realm -- way less in the basic primitives that just manage a
    single resource or memory block.

    When I say

    String a("a");
    a = "ab";
    and the latter fails with memory error I honestly see no value to make
    it strong XG, and keep original value.

    I tried to figure out what std::string is supposed to do here but choked
    ;-)

    But my point is not really the how, but that it IMO it can be reasonably
    expected to be done correctly in those rare cases, and if this is a
    problem for someone I can't imagine how he can deal with something less
    trivial.
     
    Balog Pal, Mar 22, 2013
    #6
  7. James Kanze

    Öö Tiib Guest

    On Friday, 22 March 2013 22:24:59 UTC+2, Balog Pal wrote:
    > On 3/22/2013 8:52 PM, Öö Tiib wrote:
    > > Object should remain in sane state if anything throws exceptions
    > > during assignment. Sole imaginable sane state is "like it was before".

    >
    > That is strong XG, can be done too at about the same amount of code but
    > some increased resource cost at runtime. I don't agree that strong XG is
    > the only sane way but that is up to opinion in general -- and detailed
    > design at a particular instance, so we should not debate it. :)


    I did not want to debate it. I have had bad experience with assignment
    damaging things. Since '=' is so innocent in code I feel it should be
    robust. Common case ... some GUI designer made it too permissive
    and user can do illegal copy or move. Throwing is fine since it is
    defect of GUI ... however being broken afterwards is out of question.

    Strong exception safety guarantee is not needed in lot of other cases.

    > > Lot of non-polymorphic classes may have constant or reference or
    > > unique_ptr or auto_ptr or boost::scoped_ptr or naked pointer
    > > non-static members. These classes should be made explicitly copyable
    > > or movable if one wants them to be in vector or deque or the like.

    >
    > I have a full suite of smart pointers: NC, DC, transfer and shared,
    > certainly if I want a copyable object I use a the DC variant over
    > anything else.


    Reference or constant members you avoid? shared_ptr member is quite
    common. Sometimes deep copy sometimes shared copy is needed
    when copying an object with such member. Your DC pointer is
    interesting. Does it have non-owning side-kick or do you use raw pointer
    instead? Transfer and non-copyable ... isn't it unique_ptr?

    > IMO same applies to any resource handler. (btw the said
    > pointers are policy-based so it's easy to use them for any kind of
    > resource; I recall a few times using fake-copy that was okay for the
    > case).


    I avoid allowing assignment or copying of resources like threads, files or
    sockets with just '=' character ... being laconic here is hiding the cost
    tag that certainly matters. Moving is better since it is cheaper.

    > IME starting to hand-craft an op= is the last resort and is a ticked for
    > more easy-to-break maintenance too.


    It is important to make novice to realize that compiler will create the
    things itself if it only can and that compiler does not always
    understand his intentions. If novice does not know that issue with
    classes in C++ then he is doomed to write broken classes. Everybody
    have seen copyable singletons I trust? Hiding that part of C++ does
    not work it feels.

    Note that implicit assignment operators do not even offer the
    basic exception safety guarantee on lot of cases. So either everything
    is nothrow during assignment or you *have* to hand-craft them.
     
    Öö Tiib, Mar 23, 2013
    #7
  8. Öö Tiibæ–¼ 2013å¹´3月23日星期六UTC+8下åˆ7時24分51秒寫é“:
    > On Friday, 22 March 2013 22:24:59 UTC+2, Balog Pal wrote:
    >
    > > On 3/22/2013 8:52 PM, Öö Tiib wrote:

    >
    > > > Object should remain in sane state if anything throws exceptions

    >
    > > > during assignment. Sole imaginable sane state is "like it was before"..

    >
    > >

    >
    > > That is strong XG, can be done too at about the same amount of code but

    >
    > > some increased resource cost at runtime. I don't agree that strong XG is

    >
    > > the only sane way but that is up to opinion in general -- and detailed

    >
    > > design at a particular instance, so we should not debate it. :)

    >
    >
    >
    > I did not want to debate it. I have had bad experience with assignment
    >
    > damaging things. Since '=' is so innocent in code I feel it should be
    >
    > robust. Common case ... some GUI designer made it too permissive
    >
    > and user can do illegal copy or move. Throwing is fine since it is
    >
    > defect of GUI ... however being broken afterwards is out of question.
    >
    >
    >
    > Strong exception safety guarantee is not needed in lot of other cases.
    >
    >
    >
    > > > Lot of non-polymorphic classes may have constant or reference or

    >
    > > > unique_ptr or auto_ptr or boost::scoped_ptr or naked pointer

    >
    > > > non-static members. These classes should be made explicitly copyable

    >
    > > > or movable if one wants them to be in vector or deque or the like.

    >
    > >

    >
    > > I have a full suite of smart pointers: NC, DC, transfer and shared,

    >
    > > certainly if I want a copyable object I use a the DC variant over

    >
    > > anything else.

    >
    >
    >
    > Reference or constant members you avoid? shared_ptr member is quite
    >
    > common. Sometimes deep copy sometimes shared copy is needed
    >
    > when copying an object with such member. Your DC pointer is
    >
    > interesting. Does it have non-owning side-kick or do you use raw pointer
    >
    > instead? Transfer and non-copyable ... isn't it unique_ptr?
    >
    >
    >
    > > IMO same applies to any resource handler. (btw the said

    >
    > > pointers are policy-based so it's easy to use them for any kind of

    >
    > > resource; I recall a few times using fake-copy that was okay for the

    >
    > > case).

    >
    >
    >
    > I avoid allowing assignment or copying of resources like threads, files or
    >
    > sockets with just '=' character ... being laconic here is hiding the cost
    >

    Are you building some class families which do operator
    overloading without carefully investigating the closure
    problem of any operation result involved?
     
    88888 Dihedral, Mar 24, 2013
    #8
  9. James Kanze

    Balog Pal Guest

    On 3/23/2013 12:24 PM, Öö Tiib wrote:
    > I have had bad experience with assignment
    > damaging things. Since '=' is so innocent in code I feel it should be
    > robust.


    I can understand that. In the early days I also had many problems
    related to op=. Then we learned the rule of three. Then we learned RAII,
    and sticking to that resulted elimination of hand-crafted op= and cctor
    from user code. From there I recall no problems worth mentioning.

    If I see an op= in code, my first reaction is to ask a ton of questions
    why is it there, and likely result is to send the whole class to design
    table. For good. :) In fewer cases it is just cut with slight
    modifications. In the remaining rare cases it gets a very thorough
    review considering all kind of scenarions, including self-assignment and
    exceptions at any point.

    >> I have a full suite of smart pointers: NC, DC, transfer and shared,
    >> certainly if I want a copyable object I use a the DC variant over
    >> anything else.

    >
    > Reference or constant members you avoid?


    I'm not avoiding them, but they're pretty rare turn turn up. And I can't
    recall a single case they would trigger special ops -- the natural
    consequence is a sensible default cctor and a deleted op=, that is fine
    for me. If I wrote them by hand the copy would not be "equivalent" to
    the original, and I guess that would surprise someone later on.

    > shared_ptr member is quite common.


    Not in my work. But I see no problem with it -- if it's used for
    sharing, then it will apply for its container just by doing nothing. (Or
    the container deletes the copy possibility and just uses it as a NC
    holder for other conveniences -- my NC pointer uses CHECKED_DELETE,
    shared_ptr is smarter than that.)

    > Sometimes deep copy sometimes shared copy is needed
    > when copying an object with such member.


    IMO it's rarther either shared or NC. If I want DC, why pick the
    shared_ptr over DC in the first place?

    > Your DC pointer is
    > interesting. Does it have non-owning side-kick or do you use raw pointer
    > instead? Transfer and non-copyable ... isn't it unique_ptr?


    'Transfer' is the plain old auto_ptr, replaced by unique_ptr these days.
    NC would have been boost::scoped_ptr, but it turned out to have crippled
    interface, so I made mine using auto_ptr's interface (I like the
    reset/release a lot, and need get regularly dealing with C-interfaced
    other components), just stripped cctor, op=, the templated ctors (mostly
    out of fear) and the deleter comes from policy. In some environments it
    got an extra member to allow external init (do reset() and provide &ptr
    to be assigned) where such approach to create new objects is common.

    >> IMO same applies to any resource handler. (btw the said
    >> pointers are policy-based so it's easy to use them for any kind of
    >> resource; I recall a few times using fake-copy that was okay for the
    >> case).

    >
    > I avoid allowing assignment or copying of resources like threads, files or
    > sockets with just '=' character ... being laconic here is hiding the cost
    > tag that certainly matters. Moving is better since it is cheaper.


    I used all of those only for NC. Certainly move would make sense, but
    the compilers I use did not yet pick up move semantics properly,
    eventually I'll switch to more of that.

    >> IME starting to hand-craft an op= is the last resort and is a ticked for
    >> more easy-to-break maintenance too.

    >
    > It is important to make novice to realize that compiler will create the
    > things itself if it only can and that compiler does not always
    > understand his intentions.


    Rule of 3 covers that, and certainly a novice shall never gain check-in
    rights before mastering that (along with rest of EC++3rd)...

    > If novice does not know that issue with
    > classes in C++ then he is doomed to write broken classes. Everybody
    > have seen copyable singletons I trust? Hiding that part of C++ does
    > not work it feels.


    .... but knowing those details do not map directly to design and coding,
    there's way more. And broken classes are supposed to be caught on
    review. sure, novices are doomed to write a ton of them before gaining
    wisdom to get it right on the first attempt. and with strict meaning of
    'broken' I guess even veterans fail with the first attempt more often
    than not. ;-)))

    IRL we fight program complexity on a broader level, that usually imposes
    restrictions on how objects are created, held, disposed of; implicit
    responsibilities for some actions, forbidding some other activity (like
    storing pointers/refs to a thing you can't prove to live long enough).

    > Note that implicit assignment operators do not even offer the
    > basic exception safety guarantee on lot of cases.


    They do memberwise assignment, that I recall was fine for all my value
    classes. I try to imagine a broken situation, but the only scenario
    jumps to mind is when I have a group of members that shall be in synch
    and one may throw on copy -- my first question would be "how come that
    group is not a class in its own right?"

    > So either everything
    > is nothrow during assignment or you *have* to hand-craft them.


    IMO we're lightyears from that.
     
    Balog Pal, Mar 24, 2013
    #9
  10. James Kanze

    Öö Tiib Guest

    On Sunday, 24 March 2013 13:44:19 UTC+2, Balog Pal wrote:
    > On 3/23/2013 12:24 PM, Öö Tiib wrote:
    > > Reference or constant members you avoid?

    >
    > I'm not avoiding them, but they're pretty rare turn turn up. And I can't
    > recall a single case they would trigger special ops -- the natural
    > consequence is a sensible default cctor and a deleted op=, that is fine
    > for me. If I wrote them by hand the copy would not be "equivalent" to
    > the original, and I guess that would surprise someone later on.


    Yes, copyability is less common than language designer originally
    thought IMO ... but movability is more usual. Constants are quite
    common members. It is quite frequently suggested to use immutability
    wherever it makes sense.

    Reference is very close to constant not-null pointer. I often have
    references in components to track relation back to composite. If
    moving components around makes sense (not often) then there is
    assignment needed. Such assignment can assert that the composite
    references are already equal or throw logic_error if they aren't
    because assigning components of different composite does not make
    sense.

    ....
    > > Sometimes deep copy sometimes shared copy is needed
    > > when copying an object with such member.

    >
    > IMO it's rarther either shared or NC. If I want DC, why pick the
    > shared_ptr over DC in the first place?


    Because shared_ptr has handy non-owning (but tracking) partner. I need to
    think how to make similar thing to deep copy pointer. I already asked it:

    > > Your DC pointer is
    > > interesting. Does it have non-owning side-kick or do you use raw pointer
    > > instead?


    ....
    > IRL we fight program complexity on a broader level, that usually imposes
    > restrictions on how objects are created, held, disposed of; implicit
    > responsibilities for some actions, forbidding some other activity (like
    > storing pointers/refs to a thing you can't prove to live long enough).


    An object that stores pointer has to have ability to track the lifetime
    of pointed at object, simplest case is when the life time of two objects
    is bound (either way), reference count is powerful way to track, as are
    various signaling and observing systems.

    > > Note that implicit assignment operators do not even offer the
    > > basic exception safety guarantee on lot of cases.

    >
    > They do memberwise assignment, that I recall was fine for all my value
    > classes. I try to imagine a broken situation, but the only scenario
    > jumps to mind is when I have a group of members that shall be in synch
    > and one may throw on copy -- my first question would be "how come that
    > group is not a class in its own right?"


    It is. It is such "group" whose members are interrelated that we are
    usually talking about when talking about classes. Lot of combinations of
    values of members of classes are usually invalid. So now we talk
    about copy-assignment and move-assignment of such groups. Half assignment
    can end with invalid combination.

    > > So either everything
    > > is nothrow during assignment or you *have* to hand-craft them.

    >
    > IMO we're lightyears from that.


    We are ligtyears from everything being nothrow during copy-assignment,
    with move-assignment we are commonly there.
     
    Öö Tiib, Mar 24, 2013
    #10
  11. James Kanze

    James Kanze Guest

    On Saturday, March 23, 2013 11:24:51 AM UTC, Öö Tiib wrote:
    > On Friday, 22 March 2013 22:24:59 UTC+2, Balog Pal wrote:
    > > On 3/22/2013 8:52 PM, Öö Tiib wrote:
    > > > Object should remain in sane state if anything throws exceptions
    > > > during assignment. Sole imaginable sane state is "like it was before"..


    > > That is strong XG, can be done too at about the same amount of code but
    > > some increased resource cost at runtime. I don't agree that strong XG is
    > > the only sane way but that is up to opinion in general -- and detailed
    > > design at a particular instance, so we should not debate it. :)


    > I did not want to debate it.


    There's no reason to debate. It depends on the application.
    I've worked a lot on large servers; in this case, there are two
    categories of objects: those which have been created in the
    context of the request, and "permanent" obejcts, which will be
    accessible in future requests. For the first, the only
    guarantee which is necessary is that they can be destructed.
    The second require the strong guarantee. (Although one
    possibility, which I often use, is to make copies of these
    objects, and modify them, swapping them in in the commit phase.)

    > I have had bad experience with assignment
    > damaging things.


    There's damage, and there's damage. I think every one would
    agree that leaving an object in a state where it cannot be
    destructed is unacceptable. Always. For the rest, all that is
    required for temporary objects, created in the context of a
    transaction, is that they can be destructed.

    > Since '=' is so innocent in code I feel it should be
    > robust. Common case ... some GUI designer made it too permissive
    > and user can do illegal copy or move. Throwing is fine since it is
    > defect of GUI ... however being broken afterwards is out of question.


    For most objects where it is important, the obvious solution is
    to not support assignment. In my experience (which does *not*
    include all application domains), all that is needed for objects
    which support assignment is that the results can be destructed
    (the weakest acceptable guarantee). But in my experience, there
    is a large category of objects which don't support assignment.

    --
    James
     
    James Kanze, Mar 24, 2013
    #11
  12. James Kanze

    James Kanze Guest

    On Friday, March 22, 2013 8:51:42 PM UTC, Balog Pal wrote:
    > On 3/22/2013 9:11 PM, James Kanze wrote:
    > >> Taking your example, my code would call Dispose() that will call the
    > >> proper delete and set the pointer to NULL, then we proceed to allocation
    > >> part. Should it fail we're in a proper non-owning state fulfilling the
    > >> basic XG.


    > > That's doing things the hard way. As a general rule, you should
    > > construct all of the new values before you start tearing down
    > > anything.


    > That's also a fair approach if having both new and old around is not
    > considered risk for resource overuse.


    That could be a consideration in certain cases. Never the less,
    if you're working in a transaction system, at some point, you do
    need to be able to restore the original version. Unless memory
    issues are a concern, the simplest solution involves saving a
    copy of the original value. (I've never had to implement this
    in contexts where memory was an issue, so I can't comment on
    this.)

    > IMO that general rule applies to complex situations, mostly in the
    > application realm -- way less in the basic primitives that just manage a
    > single resource or memory block.


    > When I say


    > String a("a");
    > a = "ab";
    > and the latter fails with memory error I honestly see no value to make
    > it strong XG, and keep original value.


    Totally agreed. All that is required (IMHO) is that a be
    destructable.

    > I tried to figure out what std::string is supposed to do here but choked
    > ;-)


    I wouldn't swear to it, but I think that the standard requires
    the strong guarantee here: that if there is an exception in the
    assignment, that the value of a be unchanged. (In the case of
    std::string, this is relatively easy to implement.) In
    practice, of course, I find it difficult to imagine a case where
    more is needed than that a be destructible.

    --
    James
     
    James Kanze, Mar 24, 2013
    #12
  13. James Kanze

    Öö Tiib Guest

    On Sunday, 24 March 2013 16:45:58 UTC+2, James Kanze wrote:
    > On Saturday, March 23, 2013 11:24:51 AM UTC, Öö Tiib wrote:
    > > On Friday, 22 March 2013 22:24:59 UTC+2, Balog Pal wrote:
    > > > On 3/22/2013 8:52 PM, Öö Tiib wrote:
    > > > > Object should remain in sane state if anything throws exceptions
    > > > > during assignment. Sole imaginable sane state is "like it was before".

    >
    > > > That is strong XG, can be done too at about the same amount of code but
    > > > some increased resource cost at runtime. I don't agree that strong XGis
    > > > the only sane way but that is up to opinion in general -- and detailed
    > > > design at a particular instance, so we should not debate it. :)

    >
    > > I did not want to debate it.

    >
    > There's no reason to debate. It depends on the application.
    > I've worked a lot on large servers; in this case, there are two
    > categories of objects: those which have been created in the
    > context of the request, and "permanent" obejcts, which will be
    > accessible in future requests. For the first, the only
    > guarantee which is necessary is that they can be destructed.
    > The second require the strong guarantee.


    Interesting concept. How do you make difference between classes that may
    be used for temporary objects during transaction and classes that have
    used for more permanent objects? Do you have some special trait?

    > (Although one
    > possibility, which I often use, is to make copies of these
    > objects, and modify them, swapping them in in the commit phase.)


    Yes, such system-wide idiom lets to enwiden usefulness of weak quarantee.
    The problem is that ... some stuff possibly affected ... is rather
    expensive to clone (just for case).

    > > I have had bad experience with assignment
    > > damaging things.

    >
    > There's damage, and there's damage. I think every one would
    > agree that leaving an object in a state where it cannot be
    > destructed is unacceptable. Always. For the rest, all that is
    > required for temporary objects, created in the context of a
    > transaction, is that they can be destructed.
    >
    > > Since '=' is so innocent in code I feel it should be
    > > robust. Common case ... some GUI designer made it too permissive
    > > and user can do illegal copy or move. Throwing is fine since it is
    > > defect of GUI ... however being broken afterwards is out of question.

    >
    > For most objects where it is important, the obvious solution is
    > to not support assignment. In my experience (which does *not*
    > include all application domains), all that is needed for objects
    > which support assignment is that the results can be destructed
    > (the weakest acceptable guarantee). But in my experience, there
    > is a large category of objects which don't support assignment.


    I meant case where user can copy-paste or cut-paste. It is so common
    that everybody know the accelerators (ctrl-x,ctrl-c,ctrl-v) and mouse
    gestures (drag-drop, ctrl-drag-drop) to those. I often use far more sophisticated features (like serializing-unserialising) at that spot but
    on lot of cases it is in essence copy or move exposed in GUI.
     
    Öö Tiib, Mar 24, 2013
    #13
  14. Öö Tiibæ–¼ 2013å¹´3月24日星期日UTC+8下åˆ11時33分40秒寫é“:
    > On Sunday, 24 March 2013 16:45:58 UTC+2, James Kanze wrote:
    >
    > > On Saturday, March 23, 2013 11:24:51 AM UTC, Öö Tiib wrote:

    >
    > > > On Friday, 22 March 2013 22:24:59 UTC+2, Balog Pal wrote:

    >
    > > > > On 3/22/2013 8:52 PM, Öö Tiib wrote:

    >
    > > > > > Object should remain in sane state if anything throws exceptions

    >
    > > > > > during assignment. Sole imaginable sane state is "like it was before".

    >
    > >

    >
    > > > > That is strong XG, can be done too at about the same amount of codebut

    >
    > > > > some increased resource cost at runtime. I don't agree that strong XG is

    >
    > > > > the only sane way but that is up to opinion in general -- and detailed

    >
    > > > > design at a particular instance, so we should not debate it. :)

    >
    > >

    >
    > > > I did not want to debate it.

    >
    > >

    >
    > > There's no reason to debate. It depends on the application.

    >
    > > I've worked a lot on large servers; in this case, there are two

    >
    > > categories of objects: those which have been created in the

    >
    > > context of the request, and "permanent" obejcts, which will be

    >
    > > accessible in future requests. For the first, the only

    >
    > > guarantee which is necessary is that they can be destructed.

    >
    > > The second require the strong guarantee.

    >
    >
    >
    > Interesting concept. How do you make difference between classes that may
    >
    > be used for temporary objects during transaction and classes that have
    >
    > used for more permanent objects? Do you have some special trait?
    >
    >
    >
    > > (Although one

    >
    > > possibility, which I often use, is to make copies of these

    >
    > > objects, and modify them, swapping them in in the commit phase.)

    >
    >
    >
    > Yes, such system-wide idiom lets to enwiden usefulness of weak quarantee.
    >
    > The problem is that ... some stuff possibly affected ... is rather
    >
    > expensive to clone (just for case).
    >
    >
    >
    > > > I have had bad experience with assignment

    >
    > > > damaging things.

    >
    > >

    >
    > > There's damage, and there's damage. I think every one would

    >
    > > agree that leaving an object in a state where it cannot be

    >
    > > destructed is unacceptable. Always. For the rest, all that is

    >
    > > required for temporary objects, created in the context of a

    >
    > > transaction, is that they can be destructed.

    >
    > >

    >
    > > > Since '=' is so innocent in code I feel it should be

    >
    > > > robust. Common case ... some GUI designer made it too permissive

    >
    > > > and user can do illegal copy or move. Throwing is fine since it is

    >
    > > > defect of GUI ... however being broken afterwards is out of question.

    >
    > >

    >
    > > For most objects where it is important, the obvious solution is

    >
    > > to not support assignment. In my experience (which does *not*

    >
    > > include all application domains), all that is needed for objects

    >
    > > which support assignment is that the results can be destructed

    >
    > > (the weakest acceptable guarantee). But in my experience, there

    >
    > > is a large category of objects which don't support assignment.

    >
    >
    >
    > I meant case where user can copy-paste or cut-paste. It is so common
    >
    > that everybody know the accelerators (ctrl-x,ctrl-c,ctrl-v) and mouse
    >
    > gestures (drag-drop, ctrl-drag-drop) to those. I often use far more sophisticated features (like serializing-unserialising) at that spot but
    >
    > on lot of cases it is in essence copy or move exposed in GUI.


    A lot programmers are exploring more subtle
    problems in true distributed programming languages such as
    Erlang.
     
    88888 Dihedral, Mar 24, 2013
    #14
  15. James Kanze

    James Kanze Guest

    On Sunday, March 24, 2013 3:33:40 PM UTC, Öö Tiib wrote:
    > On Sunday, 24 March 2013 16:45:58 UTC+2, James Kanze wrote:
    > > On Saturday, March 23, 2013 11:24:51 AM UTC, Öö Tiib wrote:
    > > > On Friday, 22 March 2013 22:24:59 UTC+2, Balog Pal wrote:
    > > > > On 3/22/2013 8:52 PM, Öö Tiib wrote:
    > > > > > Object should remain in sane state if anything throws exceptions
    > > > > > during assignment. Sole imaginable sane state is "like it was before".


    > > > > That is strong XG, can be done too at about the same amount of codebut
    > > > > some increased resource cost at runtime. I don't agree that strong XG is
    > > > > the only sane way but that is up to opinion in general -- and detailed
    > > > > design at a particular instance, so we should not debate it. :)


    > > > I did not want to debate it.


    > > There's no reason to debate. It depends on the application.
    > > I've worked a lot on large servers; in this case, there are two
    > > categories of objects: those which have been created in the
    > > context of the request, and "permanent" obejcts, which will be
    > > accessible in future requests. For the first, the only
    > > guarantee which is necessary is that they can be destructed.
    > > The second require the strong guarantee.


    > Interesting concept. How do you make difference between classes that may
    > be used for temporary objects during transaction and classes that have
    > used for more permanent objects? Do you have some special trait?


    You design your application. Classes are designed to fulfill a
    specific role in the application. That pretty much determines
    the use they will have.

    > > (Although one
    > > possibility, which I often use, is to make copies of these
    > > objects, and modify them, swapping them in in the commit phase.)


    > Yes, such system-wide idiom lets to enwiden usefulness of weak quarantee.
    > The problem is that ... some stuff possibly affected ... is rather
    > expensive to clone (just for case).


    Such system-wide idioms are part of the requirements
    specification, at least in servers. You *must* implement
    rollback somehow. To my knowledge, there are only two
    possibilities: cloning the object, or providing some sort of
    "undo" facility. An undo facility is significantly more
    complex. And realistically, for a large server, only a small
    percentage of the objects will be involved in any single
    transaction, so the impact on memory usage can't really be
    significant. (There are probably exceptions, but I've not seen
    them in practice.)

    [...]
    > > > Since '=' is so innocent in code I feel it should be
    > > > robust. Common case ... some GUI designer made it too permissive
    > > > and user can do illegal copy or move. Throwing is fine since it is
    > > > defect of GUI ... however being broken afterwards is out of question.


    > > For most objects where it is important, the obvious solution is
    > > to not support assignment. In my experience (which does *not*
    > > include all application domains), all that is needed for objects
    > > which support assignment is that the results can be destructed
    > > (the weakest acceptable guarantee). But in my experience, there
    > > is a large category of objects which don't support assignment.


    > I meant case where user can copy-paste or cut-paste. It is so
    > common that everybody know the accelerators
    > (ctrl-x,ctrl-c,ctrl-v) and mouse gestures (drag-drop,
    > ctrl-drag-drop) to those. I often use far more sophisticated
    > features (like serializing-unserialising) at that spot but on
    > lot of cases it is in essence copy or move exposed in GUI.


    I'm not sure I follow you. Most applications aren't connected
    to a terminal or a GUI window. And things like copy/paste are
    purely GUI---how they map to application data depends on the
    application. You could use assignment, but you're certainly not
    obliged to. (For small scall copy/paste, classes like
    `std::string` definitely should use assignment. For
    copy/pasting larger entities: GUI objects generally need to know
    their parent, and are usually polymorphic, so value assignment
    doesn't work anyway.)

    --
    James
     
    James Kanze, Mar 24, 2013
    #15
  16. James Kanze

    Öö Tiib Guest

    On Sunday, 24 March 2013 21:26:22 UTC+2, James Kanze wrote:
    > On Sunday, March 24, 2013 3:33:40 PM UTC, Öö Tiib wrote:
    > > I meant case where user can copy-paste or cut-paste. It is so
    > > common that everybody know the accelerators
    > > (ctrl-x,ctrl-c,ctrl-v) and mouse gestures (drag-drop,
    > > ctrl-drag-drop) to those. I often use far more sophisticated
    > > features (like serializing-unserialising) at that spot but on
    > > lot of cases it is in essence copy or move exposed in GUI.

    >
    > I'm not sure I follow you. Most applications aren't connected
    > to a terminal or a GUI window.


    OK, on such cases there are other "active parts" that may have similar
    operations.

    > And things like copy/paste are
    > purely GUI---how they map to application data depends on the
    > application.


    I prefer relatively thin and specialized UI on top of possibly complex
    application logic. UI designers are more oriented to taste and
    usability and less oriented to deep logic and efficient algorithms.

    > You could use assignment, but you're certainly not
    > obliged to. (For small scall copy/paste, classes like
    > `std::string` definitely should use assignment. For
    > copy/pasting larger entities: GUI objects generally need to know
    > their parent, and are usually polymorphic, so value assignment
    > doesn't work anyway.)


    Classes containing polymorphic members do not have to be polymorphic.
    Value assignment may be used with those. Usually it is simple to
    make efficient assignment of such objects with strong exception
    guarantee. My point was that it *has* to be hand-made (as rule) to
    achieve strong XG.
     
    Öö Tiib, Mar 24, 2013
    #16
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    7
    Views:
    3,299
    James Kanze
    Feb 12, 2008
  2. Öö Tiib
    Replies:
    2
    Views:
    200
    Öö Tiib
    Mar 22, 2013
  3. Howard Hinnant
    Replies:
    4
    Views:
    189
    88888 Dihedral
    Mar 22, 2013
  4. Krishnan Shankar

    List getting extended when assigned to itself

    Krishnan Shankar, Aug 25, 2013, in forum: Python
    Replies:
    1
    Views:
    111
    Steven D'Aprano
    Aug 25, 2013
  5. Benjamin Kaplan
    Replies:
    0
    Views:
    99
    Benjamin Kaplan
    Aug 25, 2013
Loading...

Share This Page