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

Wikipedia:Vital articles Мазмуну Biography - Өмүр баян Philosophy and psychology - Философия жана психология Religion - Дин Social sciences - Коомдук илимдер Language and literature - Тил жана адабият Science - Илим Technology - Технология Arts and recreation - Искусство жана эс алуу History and geography - Тарых жана география Навигация менюсу

Bruxelas-Capital Índice Historia | Composición | Situación lingüística | Clima | Cidades irmandadas | Notas | Véxase tamén | Menú de navegacióneO uso das linguas en Bruxelas e a situación do neerlandés"Rexión de Bruxelas Capital"o orixinalSitio da rexiónPáxina de Bruselas no sitio da Oficina de Promoción Turística de Valonia e BruxelasMapa Interactivo da Rexión de Bruxelas-CapitaleeWorldCat332144929079854441105155190212ID28008674080552-90000 0001 0666 3698n94104302ID540940339365017018237

What should I write in an apology letter, since I have decided not to join a company after accepting an offer letterShould I keep looking after accepting a job offer?What should I do when I've been verbally told I would get an offer letter, but still haven't gotten one after 4 weeks?Do I accept an offer from a company that I am not likely to join?New job hasn't confirmed starting date and I want to give current employer as much notice as possibleHow should I address my manager in my resignation letter?HR delayed background verification, now jobless as resignedNo email communication after accepting a formal written offer. How should I phrase the call?What should I do if after receiving a verbal offer letter I am informed that my written job offer is put on hold due to some internal issues?Should I inform the current employer that I am about to resign within 1-2 weeks since I have signed the offer letter and waiting for visa?What company will do, if I send their offer letter to another company