Are there situations when self-assignment is useful?What is a smart pointer and when should I use one?When...
How strong are Wi-Fi signals?
Windows 10 Programs start without visual Interface
Where is the encrypted mask value?
Why colon to denote that a value belongs to a type?
Plot twist where the antagonist wins
Is CD audio quality good enough for the final delivery of music?
Is it ok to put a subplot to a story that is never meant to contribute to the development of the main plot?
Why do they consider the Ori false gods?
Why is desire the root of suffering?
What is the largest (size) solid object ever dropped from an airplane to impact the ground in freefall?
Is floating in space similar to falling under gravity?
General purpose replacement for enum with FlagsAttribute
Why are C64 games inconsistent with which joystick port they use?
Riley Rebuses that Share a Common Theme
Geological aftereffects of an asteroid impact on a large mountain range?
What are the benefits of cryosleep?
Should I disclose a colleague's illness (that I should not know about) when others badmouth him
How to capture more stars?
How can people dance around bonfires on Lag Lo'Omer - it's darchei emori?
Rename photos to match video titles
When did God say "let all the angels of God worship him" as stated in Hebrews 1:6?
Is there a general effective method to solve Smullyan style Knights and Knaves problems? Is the truth table method the most appropriate one?
Why are these traces shaped in such way?
What is the 中 in ダウンロード中?
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?Overloading assignment operator in C++Assignment operator - Self-assignmentWhy don't Java's +=, -=, *=, /= compound assignment operators require casting?Overloading member access operators ->, .* (C++)Replacing a 32-bit loop counter with 64-bit introduces crazy performance deviationsPOD structs containing constant memberChecking for self-assignment when overloading operator= for template class of generic type
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}
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;
}
c++ assignment-operator
|
show 6 more comments
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;
}
c++ assignment-operator
2
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
9 hours ago
1
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
9 hours ago
2
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
8 hours ago
2
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
8 hours ago
2
You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move
– chris
8 hours ago
|
show 6 more comments
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;
}
c++ assignment-operator
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;
}
c++ assignment-operator
c++ assignment-operator
edited 5 hours ago
Boann
37.9k1291123
37.9k1291123
asked 9 hours ago
aparparaaparpara
777115
777115
2
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
9 hours ago
1
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
9 hours ago
2
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
8 hours ago
2
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
8 hours ago
2
You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move
– chris
8 hours ago
|
show 6 more comments
2
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
9 hours ago
1
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
9 hours ago
2
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
8 hours ago
2
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
8 hours ago
2
You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move
– chris
8 hours ago
2
2
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
9 hours ago
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
9 hours ago
1
1
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
9 hours ago
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
9 hours ago
2
2
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
8 hours ago
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
8 hours ago
2
2
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
8 hours ago
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
8 hours ago
2
2
You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move
– chris
8 hours ago
You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move
– chris
8 hours ago
|
show 6 more comments
3 Answers
3
active
oldest
votes
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.
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 likefoo[i] = foo[i]
instead offoo[i] = foo[j]
or similar problems happen ridiculously often.
– VTT
8 hours ago
3
@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
8 hours ago
@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
8 mins ago
add a comment |
There are algorithms where it can happen.
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 thanif (a > b) a = b;
- now consider more complicated examples of similar things.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.
The question was about a non-trivial self-assignment.
– aparpara
8 hours ago
I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparinga
andb
and then possibly branch when checking for self assignment instead of just a single branching.
– VTT
8 hours ago
add a comment |
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.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
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 likefoo[i] = foo[i]
instead offoo[i] = foo[j]
or similar problems happen ridiculously often.
– VTT
8 hours ago
3
@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
8 hours ago
@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
8 mins ago
add a comment |
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.
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 likefoo[i] = foo[i]
instead offoo[i] = foo[j]
or similar problems happen ridiculously often.
– VTT
8 hours ago
3
@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
8 hours ago
@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
8 mins ago
add a comment |
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.
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.
answered 9 hours ago
Nicol BolasNicol Bolas
296k35493670
296k35493670
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 likefoo[i] = foo[i]
instead offoo[i] = foo[j]
or similar problems happen ridiculously often.
– VTT
8 hours ago
3
@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
8 hours ago
@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
8 mins ago
add a comment |
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 likefoo[i] = foo[i]
instead offoo[i] = foo[j]
or similar problems happen ridiculously often.
– VTT
8 hours ago
3
@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
8 hours ago
@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
8 mins ago
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
8 hours ago
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
8 hours ago
3
3
@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
8 hours ago
@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
8 hours ago
@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
8 mins ago
@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
8 mins ago
add a comment |
There are algorithms where it can happen.
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 thanif (a > b) a = b;
- now consider more complicated examples of similar things.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.
The question was about a non-trivial self-assignment.
– aparpara
8 hours ago
I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparinga
andb
and then possibly branch when checking for self assignment instead of just a single branching.
– VTT
8 hours ago
add a comment |
There are algorithms where it can happen.
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 thanif (a > b) a = b;
- now consider more complicated examples of similar things.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.
The question was about a non-trivial self-assignment.
– aparpara
8 hours ago
I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparinga
andb
and then possibly branch when checking for self assignment instead of just a single branching.
– VTT
8 hours ago
add a comment |
There are algorithms where it can happen.
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 thanif (a > b) a = b;
- now consider more complicated examples of similar things.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.
There are algorithms where it can happen.
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 thanif (a > b) a = b;
- now consider more complicated examples of similar things.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.
edited 8 hours ago
Jesper Juhl
18.9k32751
18.9k32751
answered 8 hours ago
davidbakdavidbak
2,71522036
2,71522036
The question was about a non-trivial self-assignment.
– aparpara
8 hours ago
I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparinga
andb
and then possibly branch when checking for self assignment instead of just a single branching.
– VTT
8 hours ago
add a comment |
The question was about a non-trivial self-assignment.
– aparpara
8 hours ago
I'd say the possibly handled self assignment makes case (1) more complicated, because we first need to branch when comparinga
andb
and then possibly branch when checking for self assignment instead of just a single branching.
– VTT
8 hours ago
The question was about a non-trivial self-assignment.
– aparpara
8 hours ago
The question was about a non-trivial self-assignment.
– aparpara
8 hours ago
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
8 hours ago
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
8 hours ago
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered 4 mins ago
max630max630
5,56411542
5,56411542
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
2
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
9 hours ago
1
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
9 hours ago
2
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
8 hours ago
2
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
8 hours ago
2
You might find this to be an interesting read: ericniebler.com/2017/03/31/post-conditions-on-self-move
– chris
8 hours ago