What happens during ++iter = iter?
I had a typo in code recently, that was causing an infinite loop in some cases (but not in all environments, it seems).
It looked like this:
for (std::vector<myString>::iterator iter = myVector.begin(); iter != myVector.end(); ++iter = iter)
{
...
}
The typo is the assignment of the iterator to itself. Removing it fixes the issues.
I am wondering what exactly happens during the statement ++iter = iter?
I thought that according to operator precedence, iterator should first be incremented, then assigned to self, but I seem to be missing some steps (otherwise there would not be infinite loops).
My feeling is that it also involves dereferencing of the variable, but I am not sure to completely understand what was happening with this bug.
Also, why did it seem to not cause infinite loops on some platforms?
c++
|
show 2 more comments
I had a typo in code recently, that was causing an infinite loop in some cases (but not in all environments, it seems).
It looked like this:
for (std::vector<myString>::iterator iter = myVector.begin(); iter != myVector.end(); ++iter = iter)
{
...
}
The typo is the assignment of the iterator to itself. Removing it fixes the issues.
I am wondering what exactly happens during the statement ++iter = iter?
I thought that according to operator precedence, iterator should first be incremented, then assigned to self, but I seem to be missing some steps (otherwise there would not be infinite loops).
My feeling is that it also involves dereferencing of the variable, but I am not sure to completely understand what was happening with this bug.
Also, why did it seem to not cause infinite loops on some platforms?
c++
"In C and also in C++, the order of any operation between two sequence points is completely up to the compiler and cannot be dependent on." is i=i++ truly a undefined behavior?.
– Yonlif
Nov 19 '18 at 20:58
A duplicate question on SO happens.
– SergeyA
Nov 19 '18 at 21:01
4
@Yonlif c++17 changes the rules rather drastically.
– n.m.
Nov 19 '18 at 21:02
I didn't know that @n.m. , could you add a link? :)
– Yonlif
Nov 19 '18 at 21:05
1
I have reopened the question because the proposed dupe is obsolete, due to the new C++17 rules.
– n.m.
Nov 19 '18 at 21:14
|
show 2 more comments
I had a typo in code recently, that was causing an infinite loop in some cases (but not in all environments, it seems).
It looked like this:
for (std::vector<myString>::iterator iter = myVector.begin(); iter != myVector.end(); ++iter = iter)
{
...
}
The typo is the assignment of the iterator to itself. Removing it fixes the issues.
I am wondering what exactly happens during the statement ++iter = iter?
I thought that according to operator precedence, iterator should first be incremented, then assigned to self, but I seem to be missing some steps (otherwise there would not be infinite loops).
My feeling is that it also involves dereferencing of the variable, but I am not sure to completely understand what was happening with this bug.
Also, why did it seem to not cause infinite loops on some platforms?
c++
I had a typo in code recently, that was causing an infinite loop in some cases (but not in all environments, it seems).
It looked like this:
for (std::vector<myString>::iterator iter = myVector.begin(); iter != myVector.end(); ++iter = iter)
{
...
}
The typo is the assignment of the iterator to itself. Removing it fixes the issues.
I am wondering what exactly happens during the statement ++iter = iter?
I thought that according to operator precedence, iterator should first be incremented, then assigned to self, but I seem to be missing some steps (otherwise there would not be infinite loops).
My feeling is that it also involves dereferencing of the variable, but I am not sure to completely understand what was happening with this bug.
Also, why did it seem to not cause infinite loops on some platforms?
c++
c++
asked Nov 19 '18 at 20:50
wipwip
1,19322041
1,19322041
"In C and also in C++, the order of any operation between two sequence points is completely up to the compiler and cannot be dependent on." is i=i++ truly a undefined behavior?.
– Yonlif
Nov 19 '18 at 20:58
A duplicate question on SO happens.
– SergeyA
Nov 19 '18 at 21:01
4
@Yonlif c++17 changes the rules rather drastically.
– n.m.
Nov 19 '18 at 21:02
I didn't know that @n.m. , could you add a link? :)
– Yonlif
Nov 19 '18 at 21:05
1
I have reopened the question because the proposed dupe is obsolete, due to the new C++17 rules.
– n.m.
Nov 19 '18 at 21:14
|
show 2 more comments
"In C and also in C++, the order of any operation between two sequence points is completely up to the compiler and cannot be dependent on." is i=i++ truly a undefined behavior?.
– Yonlif
Nov 19 '18 at 20:58
A duplicate question on SO happens.
– SergeyA
Nov 19 '18 at 21:01
4
@Yonlif c++17 changes the rules rather drastically.
– n.m.
Nov 19 '18 at 21:02
I didn't know that @n.m. , could you add a link? :)
– Yonlif
Nov 19 '18 at 21:05
1
I have reopened the question because the proposed dupe is obsolete, due to the new C++17 rules.
– n.m.
Nov 19 '18 at 21:14
"In C and also in C++, the order of any operation between two sequence points is completely up to the compiler and cannot be dependent on." is i=i++ truly a undefined behavior?.
– Yonlif
Nov 19 '18 at 20:58
"In C and also in C++, the order of any operation between two sequence points is completely up to the compiler and cannot be dependent on." is i=i++ truly a undefined behavior?.
– Yonlif
Nov 19 '18 at 20:58
A duplicate question on SO happens.
– SergeyA
Nov 19 '18 at 21:01
A duplicate question on SO happens.
– SergeyA
Nov 19 '18 at 21:01
4
4
@Yonlif c++17 changes the rules rather drastically.
– n.m.
Nov 19 '18 at 21:02
@Yonlif c++17 changes the rules rather drastically.
– n.m.
Nov 19 '18 at 21:02
I didn't know that @n.m. , could you add a link? :)
– Yonlif
Nov 19 '18 at 21:05
I didn't know that @n.m. , could you add a link? :)
– Yonlif
Nov 19 '18 at 21:05
1
1
I have reopened the question because the proposed dupe is obsolete, due to the new C++17 rules.
– n.m.
Nov 19 '18 at 21:14
I have reopened the question because the proposed dupe is obsolete, due to the new C++17 rules.
– n.m.
Nov 19 '18 at 21:14
|
show 2 more comments
1 Answer
1
active
oldest
votes
according to operator precedence, iterator should first be incremented, then assigned to self
Operator precedence does not determine evaluation order.
If the expression d = (a+b)*c
, a
, b
, c
and d
can be evaluated in any order. a+b
has to be evaluated after a
and b
, (a+b)*c
after both a+b
and c
, and the result of the assignment after both d
and the result of the multiplication, but that's about it.
The same used to be the case with the assignment.
The left-hand side and the right-hand side of the assignment previously could be evaluated in any order. In particular, the following order could be realised:
iter
is evaluated, resulting in a value we calltemp
++iter
is evaluated (this doesn't affecttemp
)
- this results in incrementing of
iter
, and the value is the newly-incrementediter
rvalue
- this results in incrementing of
temp
is assigned to theiter
rvalue evaluated above- the net result is
iter
being unchanged
Another evaluation order also used to be possible.
++iter
is evaluated
- this results in incrementing of
iter
, and the value is the newly-incrementediter
rvalue
- this results in incrementing of
iter
(the right hand side of the assignment) is evaluated again
- the result is the newly-incremented
iter
converted to lvalue
- the result is the newly-incremented
- the assignment takes place, leaving
iter
incremented as expected.
However C++17 has changed this. Assignment is now evaluated strictly from right to left. This means the first evaluation order is now guaranteed, and the second one is not allowed.
Thank you for the explanations. Maybe adding pseudo-code illustrating the two evaluation orders that used to be possible, would be useful?
– wip
Nov 20 '18 at 1:02
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%2f53382444%2fwhat-happens-during-iter-iter%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
according to operator precedence, iterator should first be incremented, then assigned to self
Operator precedence does not determine evaluation order.
If the expression d = (a+b)*c
, a
, b
, c
and d
can be evaluated in any order. a+b
has to be evaluated after a
and b
, (a+b)*c
after both a+b
and c
, and the result of the assignment after both d
and the result of the multiplication, but that's about it.
The same used to be the case with the assignment.
The left-hand side and the right-hand side of the assignment previously could be evaluated in any order. In particular, the following order could be realised:
iter
is evaluated, resulting in a value we calltemp
++iter
is evaluated (this doesn't affecttemp
)
- this results in incrementing of
iter
, and the value is the newly-incrementediter
rvalue
- this results in incrementing of
temp
is assigned to theiter
rvalue evaluated above- the net result is
iter
being unchanged
Another evaluation order also used to be possible.
++iter
is evaluated
- this results in incrementing of
iter
, and the value is the newly-incrementediter
rvalue
- this results in incrementing of
iter
(the right hand side of the assignment) is evaluated again
- the result is the newly-incremented
iter
converted to lvalue
- the result is the newly-incremented
- the assignment takes place, leaving
iter
incremented as expected.
However C++17 has changed this. Assignment is now evaluated strictly from right to left. This means the first evaluation order is now guaranteed, and the second one is not allowed.
Thank you for the explanations. Maybe adding pseudo-code illustrating the two evaluation orders that used to be possible, would be useful?
– wip
Nov 20 '18 at 1:02
add a comment |
according to operator precedence, iterator should first be incremented, then assigned to self
Operator precedence does not determine evaluation order.
If the expression d = (a+b)*c
, a
, b
, c
and d
can be evaluated in any order. a+b
has to be evaluated after a
and b
, (a+b)*c
after both a+b
and c
, and the result of the assignment after both d
and the result of the multiplication, but that's about it.
The same used to be the case with the assignment.
The left-hand side and the right-hand side of the assignment previously could be evaluated in any order. In particular, the following order could be realised:
iter
is evaluated, resulting in a value we calltemp
++iter
is evaluated (this doesn't affecttemp
)
- this results in incrementing of
iter
, and the value is the newly-incrementediter
rvalue
- this results in incrementing of
temp
is assigned to theiter
rvalue evaluated above- the net result is
iter
being unchanged
Another evaluation order also used to be possible.
++iter
is evaluated
- this results in incrementing of
iter
, and the value is the newly-incrementediter
rvalue
- this results in incrementing of
iter
(the right hand side of the assignment) is evaluated again
- the result is the newly-incremented
iter
converted to lvalue
- the result is the newly-incremented
- the assignment takes place, leaving
iter
incremented as expected.
However C++17 has changed this. Assignment is now evaluated strictly from right to left. This means the first evaluation order is now guaranteed, and the second one is not allowed.
Thank you for the explanations. Maybe adding pseudo-code illustrating the two evaluation orders that used to be possible, would be useful?
– wip
Nov 20 '18 at 1:02
add a comment |
according to operator precedence, iterator should first be incremented, then assigned to self
Operator precedence does not determine evaluation order.
If the expression d = (a+b)*c
, a
, b
, c
and d
can be evaluated in any order. a+b
has to be evaluated after a
and b
, (a+b)*c
after both a+b
and c
, and the result of the assignment after both d
and the result of the multiplication, but that's about it.
The same used to be the case with the assignment.
The left-hand side and the right-hand side of the assignment previously could be evaluated in any order. In particular, the following order could be realised:
iter
is evaluated, resulting in a value we calltemp
++iter
is evaluated (this doesn't affecttemp
)
- this results in incrementing of
iter
, and the value is the newly-incrementediter
rvalue
- this results in incrementing of
temp
is assigned to theiter
rvalue evaluated above- the net result is
iter
being unchanged
Another evaluation order also used to be possible.
++iter
is evaluated
- this results in incrementing of
iter
, and the value is the newly-incrementediter
rvalue
- this results in incrementing of
iter
(the right hand side of the assignment) is evaluated again
- the result is the newly-incremented
iter
converted to lvalue
- the result is the newly-incremented
- the assignment takes place, leaving
iter
incremented as expected.
However C++17 has changed this. Assignment is now evaluated strictly from right to left. This means the first evaluation order is now guaranteed, and the second one is not allowed.
according to operator precedence, iterator should first be incremented, then assigned to self
Operator precedence does not determine evaluation order.
If the expression d = (a+b)*c
, a
, b
, c
and d
can be evaluated in any order. a+b
has to be evaluated after a
and b
, (a+b)*c
after both a+b
and c
, and the result of the assignment after both d
and the result of the multiplication, but that's about it.
The same used to be the case with the assignment.
The left-hand side and the right-hand side of the assignment previously could be evaluated in any order. In particular, the following order could be realised:
iter
is evaluated, resulting in a value we calltemp
++iter
is evaluated (this doesn't affecttemp
)
- this results in incrementing of
iter
, and the value is the newly-incrementediter
rvalue
- this results in incrementing of
temp
is assigned to theiter
rvalue evaluated above- the net result is
iter
being unchanged
Another evaluation order also used to be possible.
++iter
is evaluated
- this results in incrementing of
iter
, and the value is the newly-incrementediter
rvalue
- this results in incrementing of
iter
(the right hand side of the assignment) is evaluated again
- the result is the newly-incremented
iter
converted to lvalue
- the result is the newly-incremented
- the assignment takes place, leaving
iter
incremented as expected.
However C++17 has changed this. Assignment is now evaluated strictly from right to left. This means the first evaluation order is now guaranteed, and the second one is not allowed.
answered Nov 19 '18 at 21:24
n.m.n.m.
72.4k882168
72.4k882168
Thank you for the explanations. Maybe adding pseudo-code illustrating the two evaluation orders that used to be possible, would be useful?
– wip
Nov 20 '18 at 1:02
add a comment |
Thank you for the explanations. Maybe adding pseudo-code illustrating the two evaluation orders that used to be possible, would be useful?
– wip
Nov 20 '18 at 1:02
Thank you for the explanations. Maybe adding pseudo-code illustrating the two evaluation orders that used to be possible, would be useful?
– wip
Nov 20 '18 at 1:02
Thank you for the explanations. Maybe adding pseudo-code illustrating the two evaluation orders that used to be possible, would be useful?
– wip
Nov 20 '18 at 1:02
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%2f53382444%2fwhat-happens-during-iter-iter%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
"In C and also in C++, the order of any operation between two sequence points is completely up to the compiler and cannot be dependent on." is i=i++ truly a undefined behavior?.
– Yonlif
Nov 19 '18 at 20:58
A duplicate question on SO happens.
– SergeyA
Nov 19 '18 at 21:01
4
@Yonlif c++17 changes the rules rather drastically.
– n.m.
Nov 19 '18 at 21:02
I didn't know that @n.m. , could you add a link? :)
– Yonlif
Nov 19 '18 at 21:05
1
I have reopened the question because the proposed dupe is obsolete, due to the new C++17 rules.
– n.m.
Nov 19 '18 at 21:14