Are there situations when self-assignment is useful?What is a smart pointer and when should I use one?When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?When to use virtual destructors?relation between access specifiers and using initializer lists for POD types in c++0xPlain Old Data types with private members?Why don't Java's +=, -=, *=, /= compound assignment operators require casting?Does the default assignment operator call operator= on all members?Assignment Operator for an objectPOD structs containing constant memberDeleted implicitly-declared copy assignment operator

Why did the World Bank set the global poverty line at $1.90?

Transfer custom ringtones to iPhone using a computer running Linux

Why ambiguous grammars are bad?

What's the meaning of the expression "short circuit" in the text bellow?

Tikz-cd diagram arrow passing under a node - not crossing it

How durable are silver inlays on a blade?

Multiband vertical antenna not working as expected

C++ logging library

Grep Match and extract

What STL algorithm can determine if exactly one item in a container satisfies a predicate?

Was planting UN flag on Moon ever discussed?

Do empty drive bays need to be filled?

Are the guests in Westworld forbidden to tell the hosts that they are robots?

Extracting data from Plot

Assigning function to function pointer, const argument correctness?

If there's something that implicates the president why is there then a national security issue? (John Dowd)

Is Dumbledore a human lie detector?

I've been given a project I can't complete, what should I do?

bash vs. zsh: What are the practical differences?

Can the removal of a duty-free sales trolley result in a measurable reduction in emissions?

Difference templates and layouts

Why isn't Bash trap working if output is redirected to stdout?

Is the Keras Embedding layer dependent on the target label?

Why are MBA programs closing in the United States?



Are there situations when self-assignment is useful?


What is a smart pointer and when should I use one?When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?When to use virtual destructors?relation between access specifiers and using initializer lists for POD types in c++0xPlain Old Data types with private members?Why don't Java's +=, -=, *=, /= compound assignment operators require casting?Does the default assignment operator call operator= on all members?Assignment Operator for an objectPOD structs containing constant memberDeleted implicitly-declared copy assignment operator






.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;








24















It is commonly known that when implementing an assignment operator one has to protect against self-assignment, at least when the class has non-POD members. Usually it is (or is equivalent to):



Foo& operator=(const Foo& other)

if (&other == this)
return *this;
... // Do copy



What were the reasons for not inserting the self-assignment protection automatically? Are there use cases when self-assignment does something non-trivial and practically useful?



Foo& operator=(const Foo& other)

if (&other == this)

// Do something non-trivial

else

// Do copy

return *this;




To summarize the answers and discussion by now



Looks like non-trivial self-assignment can never be really useful. The only option proposed was to put an assert there in order to detect some logical errors. But there are quite legitimate self-assignment cases like a = std::min(a, b), so even this option is highly dubious.



But there are two possible implementations of a trivial self-assignment:



  1. Do nothing if &other == this. Always work, though may have negative performance impact due to an extra branching. But in a user-defined assignment operator the test must be almost always explicitly made.

  2. Copy each member to itself. This is what is done by default. If the members use default assignment operators as well, it may be faster, because doesn't requre an extra branching.

I still don't see why the C++ standard could not guarantee that in a user-defined assignment operator &other != this. If you want no branching, use the default operator. If you are redefining the operator, some test is needed anyway...










share|improve this question



















  • 3





    This is an interesting question. I would even say that typically self-assignment is an indicator of some sort of logic error and it makes sense to use an assertion or other form of strict check. I can definitely imagine it being harmless, but not useful.

    – VTT
    May 26 at 18:31







  • 5





    Well, the C++ standard library is crazy enough to overload << and >> with effectful operations. Maybe they figured someone might want to do similarly crazy things with =.

    – melpomene
    May 26 at 18:39






  • 7





    The conditional branch may make "check and maybe do nothing" slower than "just do it", so the check should not be done by default.

    – molbdnilo
    May 26 at 18:45







  • 3





    I can also imagine situations where you want to know how often it happens, perhaps for performance reasons. If the language were to "hide" self-assignments, this would be difficult to analyse.

    – molbdnilo
    May 26 at 18:52






  • 2





    You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move

    – chris
    May 26 at 18:59

















24















It is commonly known that when implementing an assignment operator one has to protect against self-assignment, at least when the class has non-POD members. Usually it is (or is equivalent to):



Foo& operator=(const Foo& other)

if (&other == this)
return *this;
... // Do copy



What were the reasons for not inserting the self-assignment protection automatically? Are there use cases when self-assignment does something non-trivial and practically useful?



Foo& operator=(const Foo& other)

if (&other == this)

// Do something non-trivial

else

// Do copy

return *this;




To summarize the answers and discussion by now



Looks like non-trivial self-assignment can never be really useful. The only option proposed was to put an assert there in order to detect some logical errors. But there are quite legitimate self-assignment cases like a = std::min(a, b), so even this option is highly dubious.



But there are two possible implementations of a trivial self-assignment:



  1. Do nothing if &other == this. Always work, though may have negative performance impact due to an extra branching. But in a user-defined assignment operator the test must be almost always explicitly made.

  2. Copy each member to itself. This is what is done by default. If the members use default assignment operators as well, it may be faster, because doesn't requre an extra branching.

I still don't see why the C++ standard could not guarantee that in a user-defined assignment operator &other != this. If you want no branching, use the default operator. If you are redefining the operator, some test is needed anyway...










share|improve this question



















  • 3





    This is an interesting question. I would even say that typically self-assignment is an indicator of some sort of logic error and it makes sense to use an assertion or other form of strict check. I can definitely imagine it being harmless, but not useful.

    – VTT
    May 26 at 18:31







  • 5





    Well, the C++ standard library is crazy enough to overload << and >> with effectful operations. Maybe they figured someone might want to do similarly crazy things with =.

    – melpomene
    May 26 at 18:39






  • 7





    The conditional branch may make "check and maybe do nothing" slower than "just do it", so the check should not be done by default.

    – molbdnilo
    May 26 at 18:45







  • 3





    I can also imagine situations where you want to know how often it happens, perhaps for performance reasons. If the language were to "hide" self-assignments, this would be difficult to analyse.

    – molbdnilo
    May 26 at 18:52






  • 2





    You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move

    – chris
    May 26 at 18:59













24












24








24


2






It is commonly known that when implementing an assignment operator one has to protect against self-assignment, at least when the class has non-POD members. Usually it is (or is equivalent to):



Foo& operator=(const Foo& other)

if (&other == this)
return *this;
... // Do copy



What were the reasons for not inserting the self-assignment protection automatically? Are there use cases when self-assignment does something non-trivial and practically useful?



Foo& operator=(const Foo& other)

if (&other == this)

// Do something non-trivial

else

// Do copy

return *this;




To summarize the answers and discussion by now



Looks like non-trivial self-assignment can never be really useful. The only option proposed was to put an assert there in order to detect some logical errors. But there are quite legitimate self-assignment cases like a = std::min(a, b), so even this option is highly dubious.



But there are two possible implementations of a trivial self-assignment:



  1. Do nothing if &other == this. Always work, though may have negative performance impact due to an extra branching. But in a user-defined assignment operator the test must be almost always explicitly made.

  2. Copy each member to itself. This is what is done by default. If the members use default assignment operators as well, it may be faster, because doesn't requre an extra branching.

I still don't see why the C++ standard could not guarantee that in a user-defined assignment operator &other != this. If you want no branching, use the default operator. If you are redefining the operator, some test is needed anyway...










share|improve this question
















It is commonly known that when implementing an assignment operator one has to protect against self-assignment, at least when the class has non-POD members. Usually it is (or is equivalent to):



Foo& operator=(const Foo& other)

if (&other == this)
return *this;
... // Do copy



What were the reasons for not inserting the self-assignment protection automatically? Are there use cases when self-assignment does something non-trivial and practically useful?



Foo& operator=(const Foo& other)

if (&other == this)

// Do something non-trivial

else

// Do copy

return *this;




To summarize the answers and discussion by now



Looks like non-trivial self-assignment can never be really useful. The only option proposed was to put an assert there in order to detect some logical errors. But there are quite legitimate self-assignment cases like a = std::min(a, b), so even this option is highly dubious.



But there are two possible implementations of a trivial self-assignment:



  1. Do nothing if &other == this. Always work, though may have negative performance impact due to an extra branching. But in a user-defined assignment operator the test must be almost always explicitly made.

  2. Copy each member to itself. This is what is done by default. If the members use default assignment operators as well, it may be faster, because doesn't requre an extra branching.

I still don't see why the C++ standard could not guarantee that in a user-defined assignment operator &other != this. If you want no branching, use the default operator. If you are redefining the operator, some test is needed anyway...







c++ assignment-operator






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited May 29 at 20:25







aparpara

















asked May 26 at 18:27









aparparaaparpara

882117




882117







  • 3





    This is an interesting question. I would even say that typically self-assignment is an indicator of some sort of logic error and it makes sense to use an assertion or other form of strict check. I can definitely imagine it being harmless, but not useful.

    – VTT
    May 26 at 18:31







  • 5





    Well, the C++ standard library is crazy enough to overload << and >> with effectful operations. Maybe they figured someone might want to do similarly crazy things with =.

    – melpomene
    May 26 at 18:39






  • 7





    The conditional branch may make "check and maybe do nothing" slower than "just do it", so the check should not be done by default.

    – molbdnilo
    May 26 at 18:45







  • 3





    I can also imagine situations where you want to know how often it happens, perhaps for performance reasons. If the language were to "hide" self-assignments, this would be difficult to analyse.

    – molbdnilo
    May 26 at 18:52






  • 2





    You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move

    – chris
    May 26 at 18:59












  • 3





    This is an interesting question. I would even say that typically self-assignment is an indicator of some sort of logic error and it makes sense to use an assertion or other form of strict check. I can definitely imagine it being harmless, but not useful.

    – VTT
    May 26 at 18:31







  • 5





    Well, the C++ standard library is crazy enough to overload << and >> with effectful operations. Maybe they figured someone might want to do similarly crazy things with =.

    – melpomene
    May 26 at 18:39






  • 7





    The conditional branch may make "check and maybe do nothing" slower than "just do it", so the check should not be done by default.

    – molbdnilo
    May 26 at 18:45







  • 3





    I can also imagine situations where you want to know how often it happens, perhaps for performance reasons. If the language were to "hide" self-assignments, this would be difficult to analyse.

    – molbdnilo
    May 26 at 18:52






  • 2





    You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move

    – chris
    May 26 at 18:59







3




3





This is an interesting question. I would even say that typically self-assignment is an indicator of some sort of logic error and it makes sense to use an assertion or other form of strict check. I can definitely imagine it being harmless, but not useful.

– VTT
May 26 at 18:31






This is an interesting question. I would even say that typically self-assignment is an indicator of some sort of logic error and it makes sense to use an assertion or other form of strict check. I can definitely imagine it being harmless, but not useful.

– VTT
May 26 at 18:31





5




5





Well, the C++ standard library is crazy enough to overload << and >> with effectful operations. Maybe they figured someone might want to do similarly crazy things with =.

– melpomene
May 26 at 18:39





Well, the C++ standard library is crazy enough to overload << and >> with effectful operations. Maybe they figured someone might want to do similarly crazy things with =.

– melpomene
May 26 at 18:39




7




7





The conditional branch may make "check and maybe do nothing" slower than "just do it", so the check should not be done by default.

– molbdnilo
May 26 at 18:45






The conditional branch may make "check and maybe do nothing" slower than "just do it", so the check should not be done by default.

– molbdnilo
May 26 at 18:45





3




3





I can also imagine situations where you want to know how often it happens, perhaps for performance reasons. If the language were to "hide" self-assignments, this would be difficult to analyse.

– molbdnilo
May 26 at 18:52





I can also imagine situations where you want to know how often it happens, perhaps for performance reasons. If the language were to "hide" self-assignments, this would be difficult to analyse.

– molbdnilo
May 26 at 18:52




2




2





You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move

– chris
May 26 at 18:59





You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move

– chris
May 26 at 18:59












3 Answers
3






active

oldest

votes


















19














Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself. Consider the case where you have a user-provided assignment operator because each individual object has some kind of identifier, which you don't want to copy. Well, you can "copy" the other values just fine in self-assignment cases. So inserting an invisible self-assignment test is just adding a pointless and potentially costly conditional branch.



So it's not about self-assignment being useful; it's about self-assignment not always needing protection.



Furthermore, C++ generally doesn't like adding code like that to your code without you explicitly asking for it. It's typically done in terms of whole functions, not part of functions. Even destructor calls at the end of blocks are something you asked for when you put the object to be destroyed on the stack.






share|improve this answer


















  • 2





    OP was asking about a situation when self assignment would be useful, not about whether self-assignment protection is necessary or when it should be implemented. Also I have to disagree with "Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself." Such a check can be very helpful even if self-assignment itself is completely harmless to catch problems in calling code. Typos like foo[i] = foo[i] instead of foo[i] = foo[j] or similar problems happen ridiculously often.

    – VTT
    May 26 at 18:50







  • 6





    @VTT: The second sentence of the post is "What was the reasons for not inserting the self-assignment protection automatically?" The principle question only exists because of the assumption that this automatic protection would have been there if there wasn't some utility for the concept of self-assignment. My post counters this assumption, and once countered, the question becomes irrelevant.

    – Nicol Bolas
    May 26 at 19:09







  • 1





    @VTT "Typos like foo[i] = foo[i] instead of foo[i] = foo[j]" the provided approach does not report the typo so it is unclear how it can help fixing them.

    – max630
    May 27 at 3:35


















18














There are algorithms where it can happen.



  1. You know the lhs and rhs might be the same but it is just simpler to do the assignment than check. E.g., consider a = std::min(a,b); - simpler and perhaps easier to understand than if (a > b) a = b; - now consider more complicated examples of similar things.


  2. You don't know whether lhs and rhs might be the same, because they may have been passed in from somewhere else.


These algorithms where it can happen are not uncommon.






share|improve this answer




















  • 2





    The question was about a non-trivial self-assignment.

    – aparpara
    May 26 at 18:50











  • I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparing a and b and then possibly branch when checking for self assignment instead of just a single branching.

    – VTT
    May 26 at 18:54



















-1














I should admit I have never heard about the common knowledge like this. For a non-POD objects, a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator. So that you don't have the problem at all.



If you still need to copy the class, but there is some data which is unsafe to copy to itself, you could only override assignment for that data, and when it is used as a field, it would be used by an automatic assignment implementation of the upper level class.



As for your question, if you only need to skip doing anything the automatic "self-assignment protection" is there already, in a way. If you don't define assignment operation explicitely and let compiler use the automatic one, after inlining self-assignment may become no-op.



For example, the following code:



class A 
int a;
double b;
;

A& foo(A& input)

return (input = input);



is compiled to (gcc 4.9, -O2):



_Z3fooR1A:
.cfi_startproc
movq %rdi, %rax
ret
.cfi_endproc


Which does not copy anything.






share|improve this answer


















  • 1





    "a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator." And what about moving? Note that the OP was not specific about the form of self-assignment: copy or move. While lots of more complex types can't reasonably be copied, few are the types that cannot logically be moved.

    – Nicol Bolas
    May 27 at 4:20











  • @NicolBolas the OP's code uses copying, and I meant there copying. I guess for moving next paragraphs apply as well.

    – max630
    May 27 at 5:03











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f56316291%2fare-there-situations-when-self-assignment-is-useful%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes









19














Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself. Consider the case where you have a user-provided assignment operator because each individual object has some kind of identifier, which you don't want to copy. Well, you can "copy" the other values just fine in self-assignment cases. So inserting an invisible self-assignment test is just adding a pointless and potentially costly conditional branch.



So it's not about self-assignment being useful; it's about self-assignment not always needing protection.



Furthermore, C++ generally doesn't like adding code like that to your code without you explicitly asking for it. It's typically done in terms of whole functions, not part of functions. Even destructor calls at the end of blocks are something you asked for when you put the object to be destroyed on the stack.






share|improve this answer


















  • 2





    OP was asking about a situation when self assignment would be useful, not about whether self-assignment protection is necessary or when it should be implemented. Also I have to disagree with "Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself." Such a check can be very helpful even if self-assignment itself is completely harmless to catch problems in calling code. Typos like foo[i] = foo[i] instead of foo[i] = foo[j] or similar problems happen ridiculously often.

    – VTT
    May 26 at 18:50







  • 6





    @VTT: The second sentence of the post is "What was the reasons for not inserting the self-assignment protection automatically?" The principle question only exists because of the assumption that this automatic protection would have been there if there wasn't some utility for the concept of self-assignment. My post counters this assumption, and once countered, the question becomes irrelevant.

    – Nicol Bolas
    May 26 at 19:09







  • 1





    @VTT "Typos like foo[i] = foo[i] instead of foo[i] = foo[j]" the provided approach does not report the typo so it is unclear how it can help fixing them.

    – max630
    May 27 at 3:35















19














Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself. Consider the case where you have a user-provided assignment operator because each individual object has some kind of identifier, which you don't want to copy. Well, you can "copy" the other values just fine in self-assignment cases. So inserting an invisible self-assignment test is just adding a pointless and potentially costly conditional branch.



So it's not about self-assignment being useful; it's about self-assignment not always needing protection.



Furthermore, C++ generally doesn't like adding code like that to your code without you explicitly asking for it. It's typically done in terms of whole functions, not part of functions. Even destructor calls at the end of blocks are something you asked for when you put the object to be destroyed on the stack.






share|improve this answer


















  • 2





    OP was asking about a situation when self assignment would be useful, not about whether self-assignment protection is necessary or when it should be implemented. Also I have to disagree with "Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself." Such a check can be very helpful even if self-assignment itself is completely harmless to catch problems in calling code. Typos like foo[i] = foo[i] instead of foo[i] = foo[j] or similar problems happen ridiculously often.

    – VTT
    May 26 at 18:50







  • 6





    @VTT: The second sentence of the post is "What was the reasons for not inserting the self-assignment protection automatically?" The principle question only exists because of the assumption that this automatic protection would have been there if there wasn't some utility for the concept of self-assignment. My post counters this assumption, and once countered, the question becomes irrelevant.

    – Nicol Bolas
    May 26 at 19:09







  • 1





    @VTT "Typos like foo[i] = foo[i] instead of foo[i] = foo[j]" the provided approach does not report the typo so it is unclear how it can help fixing them.

    – max630
    May 27 at 3:35













19












19








19







Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself. Consider the case where you have a user-provided assignment operator because each individual object has some kind of identifier, which you don't want to copy. Well, you can "copy" the other values just fine in self-assignment cases. So inserting an invisible self-assignment test is just adding a pointless and potentially costly conditional branch.



So it's not about self-assignment being useful; it's about self-assignment not always needing protection.



Furthermore, C++ generally doesn't like adding code like that to your code without you explicitly asking for it. It's typically done in terms of whole functions, not part of functions. Even destructor calls at the end of blocks are something you asked for when you put the object to be destroyed on the stack.






share|improve this answer













Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself. Consider the case where you have a user-provided assignment operator because each individual object has some kind of identifier, which you don't want to copy. Well, you can "copy" the other values just fine in self-assignment cases. So inserting an invisible self-assignment test is just adding a pointless and potentially costly conditional branch.



So it's not about self-assignment being useful; it's about self-assignment not always needing protection.



Furthermore, C++ generally doesn't like adding code like that to your code without you explicitly asking for it. It's typically done in terms of whole functions, not part of functions. Even destructor calls at the end of blocks are something you asked for when you put the object to be destroyed on the stack.







share|improve this answer












share|improve this answer



share|improve this answer










answered May 26 at 18:41









Nicol BolasNicol Bolas

298k35497673




298k35497673







  • 2





    OP was asking about a situation when self assignment would be useful, not about whether self-assignment protection is necessary or when it should be implemented. Also I have to disagree with "Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself." Such a check can be very helpful even if self-assignment itself is completely harmless to catch problems in calling code. Typos like foo[i] = foo[i] instead of foo[i] = foo[j] or similar problems happen ridiculously often.

    – VTT
    May 26 at 18:50







  • 6





    @VTT: The second sentence of the post is "What was the reasons for not inserting the self-assignment protection automatically?" The principle question only exists because of the assumption that this automatic protection would have been there if there wasn't some utility for the concept of self-assignment. My post counters this assumption, and once countered, the question becomes irrelevant.

    – Nicol Bolas
    May 26 at 19:09







  • 1





    @VTT "Typos like foo[i] = foo[i] instead of foo[i] = foo[j]" the provided approach does not report the typo so it is unclear how it can help fixing them.

    – max630
    May 27 at 3:35












  • 2





    OP was asking about a situation when self assignment would be useful, not about whether self-assignment protection is necessary or when it should be implemented. Also I have to disagree with "Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself." Such a check can be very helpful even if self-assignment itself is completely harmless to catch problems in calling code. Typos like foo[i] = foo[i] instead of foo[i] = foo[j] or similar problems happen ridiculously often.

    – VTT
    May 26 at 18:50







  • 6





    @VTT: The second sentence of the post is "What was the reasons for not inserting the self-assignment protection automatically?" The principle question only exists because of the assumption that this automatic protection would have been there if there wasn't some utility for the concept of self-assignment. My post counters this assumption, and once countered, the question becomes irrelevant.

    – Nicol Bolas
    May 26 at 19:09







  • 1





    @VTT "Typos like foo[i] = foo[i] instead of foo[i] = foo[j]" the provided approach does not report the typo so it is unclear how it can help fixing them.

    – max630
    May 27 at 3:35







2




2





OP was asking about a situation when self assignment would be useful, not about whether self-assignment protection is necessary or when it should be implemented. Also I have to disagree with "Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself." Such a check can be very helpful even if self-assignment itself is completely harmless to catch problems in calling code. Typos like foo[i] = foo[i] instead of foo[i] = foo[j] or similar problems happen ridiculously often.

– VTT
May 26 at 18:50






OP was asking about a situation when self assignment would be useful, not about whether self-assignment protection is necessary or when it should be implemented. Also I have to disagree with "Self-assignment protection is only necessary for types where the code being skipped is dangerous when applied to itself." Such a check can be very helpful even if self-assignment itself is completely harmless to catch problems in calling code. Typos like foo[i] = foo[i] instead of foo[i] = foo[j] or similar problems happen ridiculously often.

– VTT
May 26 at 18:50





6




6





@VTT: The second sentence of the post is "What was the reasons for not inserting the self-assignment protection automatically?" The principle question only exists because of the assumption that this automatic protection would have been there if there wasn't some utility for the concept of self-assignment. My post counters this assumption, and once countered, the question becomes irrelevant.

– Nicol Bolas
May 26 at 19:09






@VTT: The second sentence of the post is "What was the reasons for not inserting the self-assignment protection automatically?" The principle question only exists because of the assumption that this automatic protection would have been there if there wasn't some utility for the concept of self-assignment. My post counters this assumption, and once countered, the question becomes irrelevant.

– Nicol Bolas
May 26 at 19:09





1




1





@VTT "Typos like foo[i] = foo[i] instead of foo[i] = foo[j]" the provided approach does not report the typo so it is unclear how it can help fixing them.

– max630
May 27 at 3:35





@VTT "Typos like foo[i] = foo[i] instead of foo[i] = foo[j]" the provided approach does not report the typo so it is unclear how it can help fixing them.

– max630
May 27 at 3:35













18














There are algorithms where it can happen.



  1. You know the lhs and rhs might be the same but it is just simpler to do the assignment than check. E.g., consider a = std::min(a,b); - simpler and perhaps easier to understand than if (a > b) a = b; - now consider more complicated examples of similar things.


  2. You don't know whether lhs and rhs might be the same, because they may have been passed in from somewhere else.


These algorithms where it can happen are not uncommon.






share|improve this answer




















  • 2





    The question was about a non-trivial self-assignment.

    – aparpara
    May 26 at 18:50











  • I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparing a and b and then possibly branch when checking for self assignment instead of just a single branching.

    – VTT
    May 26 at 18:54
















18














There are algorithms where it can happen.



  1. You know the lhs and rhs might be the same but it is just simpler to do the assignment than check. E.g., consider a = std::min(a,b); - simpler and perhaps easier to understand than if (a > b) a = b; - now consider more complicated examples of similar things.


  2. You don't know whether lhs and rhs might be the same, because they may have been passed in from somewhere else.


These algorithms where it can happen are not uncommon.






share|improve this answer




















  • 2





    The question was about a non-trivial self-assignment.

    – aparpara
    May 26 at 18:50











  • I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparing a and b and then possibly branch when checking for self assignment instead of just a single branching.

    – VTT
    May 26 at 18:54














18












18








18







There are algorithms where it can happen.



  1. You know the lhs and rhs might be the same but it is just simpler to do the assignment than check. E.g., consider a = std::min(a,b); - simpler and perhaps easier to understand than if (a > b) a = b; - now consider more complicated examples of similar things.


  2. You don't know whether lhs and rhs might be the same, because they may have been passed in from somewhere else.


These algorithms where it can happen are not uncommon.






share|improve this answer















There are algorithms where it can happen.



  1. You know the lhs and rhs might be the same but it is just simpler to do the assignment than check. E.g., consider a = std::min(a,b); - simpler and perhaps easier to understand than if (a > b) a = b; - now consider more complicated examples of similar things.


  2. You don't know whether lhs and rhs might be the same, because they may have been passed in from somewhere else.


These algorithms where it can happen are not uncommon.







share|improve this answer














share|improve this answer



share|improve this answer








edited May 26 at 18:48









Jesper Juhl

1




1










answered May 26 at 18:46









davidbakdavidbak

2,87122037




2,87122037







  • 2





    The question was about a non-trivial self-assignment.

    – aparpara
    May 26 at 18:50











  • I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparing a and b and then possibly branch when checking for self assignment instead of just a single branching.

    – VTT
    May 26 at 18:54













  • 2





    The question was about a non-trivial self-assignment.

    – aparpara
    May 26 at 18:50











  • I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparing a and b and then possibly branch when checking for self assignment instead of just a single branching.

    – VTT
    May 26 at 18:54








2




2





The question was about a non-trivial self-assignment.

– aparpara
May 26 at 18:50





The question was about a non-trivial self-assignment.

– aparpara
May 26 at 18:50













I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparing a and b and then possibly branch when checking for self assignment instead of just a single branching.

– VTT
May 26 at 18:54






I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparing a and b and then possibly branch when checking for self assignment instead of just a single branching.

– VTT
May 26 at 18:54












-1














I should admit I have never heard about the common knowledge like this. For a non-POD objects, a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator. So that you don't have the problem at all.



If you still need to copy the class, but there is some data which is unsafe to copy to itself, you could only override assignment for that data, and when it is used as a field, it would be used by an automatic assignment implementation of the upper level class.



As for your question, if you only need to skip doing anything the automatic "self-assignment protection" is there already, in a way. If you don't define assignment operation explicitely and let compiler use the automatic one, after inlining self-assignment may become no-op.



For example, the following code:



class A 
int a;
double b;
;

A& foo(A& input)

return (input = input);



is compiled to (gcc 4.9, -O2):



_Z3fooR1A:
.cfi_startproc
movq %rdi, %rax
ret
.cfi_endproc


Which does not copy anything.






share|improve this answer


















  • 1





    "a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator." And what about moving? Note that the OP was not specific about the form of self-assignment: copy or move. While lots of more complex types can't reasonably be copied, few are the types that cannot logically be moved.

    – Nicol Bolas
    May 27 at 4:20











  • @NicolBolas the OP's code uses copying, and I meant there copying. I guess for moving next paragraphs apply as well.

    – max630
    May 27 at 5:03















-1














I should admit I have never heard about the common knowledge like this. For a non-POD objects, a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator. So that you don't have the problem at all.



If you still need to copy the class, but there is some data which is unsafe to copy to itself, you could only override assignment for that data, and when it is used as a field, it would be used by an automatic assignment implementation of the upper level class.



As for your question, if you only need to skip doing anything the automatic "self-assignment protection" is there already, in a way. If you don't define assignment operation explicitely and let compiler use the automatic one, after inlining self-assignment may become no-op.



For example, the following code:



class A 
int a;
double b;
;

A& foo(A& input)

return (input = input);



is compiled to (gcc 4.9, -O2):



_Z3fooR1A:
.cfi_startproc
movq %rdi, %rax
ret
.cfi_endproc


Which does not copy anything.






share|improve this answer


















  • 1





    "a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator." And what about moving? Note that the OP was not specific about the form of self-assignment: copy or move. While lots of more complex types can't reasonably be copied, few are the types that cannot logically be moved.

    – Nicol Bolas
    May 27 at 4:20











  • @NicolBolas the OP's code uses copying, and I meant there copying. I guess for moving next paragraphs apply as well.

    – max630
    May 27 at 5:03













-1












-1








-1







I should admit I have never heard about the common knowledge like this. For a non-POD objects, a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator. So that you don't have the problem at all.



If you still need to copy the class, but there is some data which is unsafe to copy to itself, you could only override assignment for that data, and when it is used as a field, it would be used by an automatic assignment implementation of the upper level class.



As for your question, if you only need to skip doing anything the automatic "self-assignment protection" is there already, in a way. If you don't define assignment operation explicitely and let compiler use the automatic one, after inlining self-assignment may become no-op.



For example, the following code:



class A 
int a;
double b;
;

A& foo(A& input)

return (input = input);



is compiled to (gcc 4.9, -O2):



_Z3fooR1A:
.cfi_startproc
movq %rdi, %rax
ret
.cfi_endproc


Which does not copy anything.






share|improve this answer













I should admit I have never heard about the common knowledge like this. For a non-POD objects, a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator. So that you don't have the problem at all.



If you still need to copy the class, but there is some data which is unsafe to copy to itself, you could only override assignment for that data, and when it is used as a field, it would be used by an automatic assignment implementation of the upper level class.



As for your question, if you only need to skip doing anything the automatic "self-assignment protection" is there already, in a way. If you don't define assignment operation explicitely and let compiler use the automatic one, after inlining self-assignment may become no-op.



For example, the following code:



class A 
int a;
double b;
;

A& foo(A& input)

return (input = input);



is compiled to (gcc 4.9, -O2):



_Z3fooR1A:
.cfi_startproc
movq %rdi, %rax
ret
.cfi_endproc


Which does not copy anything.







share|improve this answer












share|improve this answer



share|improve this answer










answered May 27 at 3:39









max630max630

5,57211542




5,57211542







  • 1





    "a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator." And what about moving? Note that the OP was not specific about the form of self-assignment: copy or move. While lots of more complex types can't reasonably be copied, few are the types that cannot logically be moved.

    – Nicol Bolas
    May 27 at 4:20











  • @NicolBolas the OP's code uses copying, and I meant there copying. I guess for moving next paragraphs apply as well.

    – max630
    May 27 at 5:03












  • 1





    "a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator." And what about moving? Note that the OP was not specific about the form of self-assignment: copy or move. While lots of more complex types can't reasonably be copied, few are the types that cannot logically be moved.

    – Nicol Bolas
    May 27 at 4:20











  • @NicolBolas the OP's code uses copying, and I meant there copying. I guess for moving next paragraphs apply as well.

    – max630
    May 27 at 5:03







1




1





"a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator." And what about moving? Note that the OP was not specific about the form of self-assignment: copy or move. While lots of more complex types can't reasonably be copied, few are the types that cannot logically be moved.

– Nicol Bolas
May 27 at 4:20





"a more strict approach is to forbid copying them with disabling copy constructor and the assignment operator." And what about moving? Note that the OP was not specific about the form of self-assignment: copy or move. While lots of more complex types can't reasonably be copied, few are the types that cannot logically be moved.

– Nicol Bolas
May 27 at 4:20













@NicolBolas the OP's code uses copying, and I meant there copying. I guess for moving next paragraphs apply as well.

– max630
May 27 at 5:03





@NicolBolas the OP's code uses copying, and I meant there copying. I guess for moving next paragraphs apply as well.

– max630
May 27 at 5:03

















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f56316291%2fare-there-situations-when-self-assignment-is-useful%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Club Baloncesto Breogán Índice Historia | Pavillón | Nome | O Breogán na cultura popular | Xogadores | Adestradores | Presidentes | Palmarés | Historial | Líderes | Notas | Véxase tamén | Menú de navegacióncbbreogan.galCadroGuía oficial da ACB 2009-10, páxina 201Guía oficial ACB 1992, páxina 183. Editorial DB.É de 6.500 espectadores sentados axeitándose á última normativa"Estudiantes Junior, entre as mellores canteiras"o orixinalHemeroteca El Mundo Deportivo, 16 setembro de 1970, páxina 12Historia do BreogánAlfredo Pérez, o último canoneiroHistoria C.B. BreogánHemeroteca de El Mundo DeportivoJimmy Wright, norteamericano do Breogán deixará Lugo por ameazas de morteResultados de Breogán en 1986-87Resultados de Breogán en 1990-91Ficha de Velimir Perasović en acb.comResultados de Breogán en 1994-95Breogán arrasa al Barça. "El Mundo Deportivo", 27 de setembro de 1999, páxina 58CB Breogán - FC BarcelonaA FEB invita a participar nunha nova Liga EuropeaCharlie Bell na prensa estatalMáximos anotadores 2005Tempada 2005-06 : Tódolos Xogadores da Xornada""Non quero pensar nunha man negra, mais pregúntome que está a pasar""o orixinalRaúl López, orgulloso dos xogadores, presume da boa saúde económica do BreogánJulio González confirma que cesa como presidente del BreogánHomenaxe a Lisardo GómezA tempada do rexurdimento celesteEntrevista a Lisardo GómezEl COB dinamita el Pazo para forzar el quinto (69-73)Cafés Candelas, patrocinador del CB Breogán"Suso Lázare, novo presidente do Breogán"o orixinalCafés Candelas Breogán firma el mayor triunfo de la historiaEl Breogán realizará 17 homenajes por su cincuenta aniversario"O Breogán honra ao seu fundador e primeiro presidente"o orixinalMiguel Giao recibiu a homenaxe do PazoHomenaxe aos primeiros gladiadores celestesO home que nos amosa como ver o Breo co corazónTita Franco será homenaxeada polos #50anosdeBreoJulio Vila recibirá unha homenaxe in memoriam polos #50anosdeBreo"O Breogán homenaxeará aos seus aboados máis veteráns"Pechada ovación a «Capi» Sanmartín e Ricardo «Corazón de González»Homenaxe por décadas de informaciónPaco García volve ao Pazo con motivo do 50 aniversario"Resultados y clasificaciones""O Cafés Candelas Breogán, campión da Copa Princesa""O Cafés Candelas Breogán, equipo ACB"C.B. Breogán"Proxecto social"o orixinal"Centros asociados"o orixinalFicha en imdb.comMario Camus trata la recuperación del amor en 'La vieja música', su última película"Páxina web oficial""Club Baloncesto Breogán""C. B. Breogán S.A.D."eehttp://www.fegaba.com

Vilaño, A Laracha Índice Patrimonio | Lugares e parroquias | Véxase tamén | Menú de navegación43°14′52″N 8°36′03″O / 43.24775, -8.60070

Cegueira Índice Epidemioloxía | Deficiencia visual | Tipos de cegueira | Principais causas de cegueira | Tratamento | Técnicas de adaptación e axudas | Vida dos cegos | Primeiros auxilios | Crenzas respecto das persoas cegas | Crenzas das persoas cegas | O neno deficiente visual | Aspectos psicolóxicos da cegueira | Notas | Véxase tamén | Menú de navegación54.054.154.436928256blindnessDicionario da Real Academia GalegaPortal das Palabras"International Standards: Visual Standards — Aspects and Ranges of Vision Loss with Emphasis on Population Surveys.""Visual impairment and blindness""Presentan un plan para previr a cegueira"o orixinalACCDV Associació Catalana de Cecs i Disminuïts Visuals - PMFTrachoma"Effect of gene therapy on visual function in Leber's congenital amaurosis"1844137110.1056/NEJMoa0802268Cans guía - os mellores amigos dos cegosArquivadoEscola de cans guía para cegos en Mortágua, PortugalArquivado"Tecnología para ciegos y deficientes visuales. Recopilación de recursos gratuitos en la Red""Colorino""‘COL.diesis’, escuchar los sonidos del color""COL.diesis: Transforming Colour into Melody and Implementing the Result in a Colour Sensor Device"o orixinal"Sistema de desarrollo de sinestesia color-sonido para invidentes utilizando un protocolo de audio""Enseñanza táctil - geometría y color. Juegos didácticos para niños ciegos y videntes""Sistema Constanz"L'ocupació laboral dels cecs a l'Estat espanyol està pràcticament equiparada a la de les persones amb visió, entrevista amb Pedro ZuritaONCE (Organización Nacional de Cegos de España)Prevención da cegueiraDescrición de deficiencias visuais (Disc@pnet)Braillín, un boneco atractivo para calquera neno, con ou sen discapacidade, que permite familiarizarse co sistema de escritura e lectura brailleAxudas Técnicas36838ID00897494007150-90057129528256DOID:1432HP:0000618D001766C10.597.751.941.162C97109C0155020