1

It is recommended not to modify an object more than once in a single expression nor using it after modifying it in the same expression.

 int i = 0;
 ++++i; // UB

 ++i = i++; // OK?
  • I think that the last expression was UB before C++17 standard but now I guess it is OK because the assignment operator has become a sequence point.

So what do you think? and can you explain to me what value should i in the last expression be ++i = i++;?

I know it is of bad design to do so but it is just for education purpose. Thank you.

  • When I compile against C++17 or C++20: g++ main.cpp -std=c++17 -o prog -Wall -pedantic I still get the same warning:

    ++i = i++;
    

This is the output from GCC:

main.cpp: In function ‘int main()’: main.cpp:12:12: warning: operation on ‘i’ may be undefined [-Wsequence-point] 12 | ++i = i++; | ~^~.

Maestro
  • 2,512
  • 9
  • 24
  • 2
    I don't know why you assume that `++++i;` is UB. The side-effect of pre-increment must be sequenced before the value computation and the side-effect of the second pre-increment must be sequenced after that value computation. (That applied since C++11, before that it was different.) – user17732522 Aug 01 '22 at 00:18

1 Answers1

3

There's no sequence points now: we have sequenced-before and sequenced-after. When you have an operator= call (or any other operator@= call - built-in operator= or user-defined call), right-hand side is sequenced-before left-hand side. So ++i = i++ is valid in C++17, with i++ sequenced-before ++i.

Before C++17, as you wrote, it was UB.

lorro
  • 10,687
  • 23
  • 36
  • @user17732522 Added, thanks. As for pre-C++17, it was also in the question (OP thinks it's UB) but it makes sense to make that explicit. – lorro Aug 01 '22 at 00:18
  • I am probably being too pedantic but just as another clarification, the built-in assignment operators are not `operator=`s and don't involve a function call. (Same for other operators.) – user17732522 Aug 01 '22 at 00:20
  • you might want to add that `++++i` is well defined and always was. – bolov Aug 01 '22 at 01:14
  • @bolov: But it is said that we should never modify an object more than once or read it and modify in the same statement. So why my GCC compiler gives me such warning: `++i = i++;` gives me this warning on GCC: "/home/PaiMei57/Desktop/myproj/main.cpp|12|warning: operation on ‘i’ may be undefined [-Wsequence-point]|". – Maestro Aug 01 '22 at 23:32
  • @Maestro use `--std=c++17` or `--std=c++20` or `--std=c++1z` (on newer compilers) – lorro Aug 01 '22 at 23:35
  • @lorro: I did use it. This what arguments I've passed to the compiler: `g++ main.cpp -std=c++17 -Wall -pedantic -o prog` The same warning if I compile against c++20: `-std=c++2a`. – Maestro Aug 01 '22 at 23:36
  • 1
    @Maestro The developers of GCC decided to keep the warning although the behavior is now well-defined. I think their reasoning was that code like this shouldn't be written and to discourage writing code that would break when changing the `-std` flag. There was a bug report for that. Let me see whether I can find it again... – user17732522 Aug 02 '22 at 00:01
  • 1
    @Maestro It is actually documented as such, see `-Wsequence-point` at https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html. – user17732522 Aug 02 '22 at 00:04