1

Why i can't do the following in Objective-C?

a = (a < 10) ? (a++) : a;

or

a = (a++)

enter image description here

2 Answers2

6

The ++ in a++ is a post-increment. In short, a = a++ does the following:

int tmp = a; // get the value of a
a = a + 1 //post-increment a
a = tmp // do the assignment

As noted by others, in C this is actually undefined behavior and different compilers can order the operations differently.

Try to avoid using ++ and -- operators when you can. The operators introduce side effects which are hard to read. Why not simply write:

if (a < 10) {
   a += 1;
}
Sulthan
  • 128,090
  • 22
  • 218
  • 270
  • Sorry, I accidentally added the annex to your answer instead of mine. Removed it. – Amin Negm-Awad Nov 27 '17 at 11:15
  • `a = a++` in C is *undefined behaviour*. I have no Objective-C standard documentation, but I suspect that same holds for that language too. If that is the case, then your reasoning about the code does not hold, since *anything* can happen. – user694733 Nov 27 '17 at 11:49
  • @user694733 I suspected the behavior was undefined but I wasn't sure because I am no C expert. I wanted to explain what happens in a way a junior would understand. I will add a bigger warning. – Sulthan Nov 27 '17 at 12:10
  • Indeed, you do not have to be an C expert to see that the assignment is meaningless. And moreover these are edge cases of C you usually do not need in Objective-C. It is more for incorporated C code. – Amin Negm-Awad Nov 27 '17 at 18:51
  • @user694733 There is no Objective-C standard a all, but everybody expects that the C part of Objective-C conforms to the C standard. At least real-world compilers let you select the used C standard for compiling Objective-C sources … – Amin Negm-Awad Nov 27 '17 at 18:52
5

To extend Sulthan's answer, there are several problem with your expressions, at least the simple assignment (case 2).

A. There is no sense in doing so. Even a++ has a value (is a non-void expression) that can be assigned, it automatically assigns the result to a itself. So the best you can expect is equivalent to

a++;

The assignment cannot improve the assignment at all. But this is not the error message.

B. Sulthans replacement of the statement is a better case. It is even worse: The ++ operator has the value of a (at the beginning of the expression) and the effect to increment a at some point in future: The increment can be delayed up to the next sequence point.

The side effect of updating the stored value of the operand shall occur between the previous and the next sequence point.

(ISO/IEC 9899:TC3, 6.5.2.4, 2)

But the assignment operator = is not a sequence point (Annex C).

The following are the sequence points described in 5.1.2.3:

[Neither assignment operator nor ) is included in the list]

Therefore the expression can be replaced with what Sulthan said:

int tmp = a; // get the value of a
a = a + 1 //post-increment a
a = tmp // do the assignment

with the result, that a still contains the old value.

Or the expression can be replaced with this code …:

int tmp = a; // get the value of a
a = tmp // assignemnt
a = a + 1 // increment

… with a different result (a is incremented). This is what the error message says: There is no defined sequence (order the operations has to be applied.)

You can insert a sequence point using the comma operator , (what is the primary use of it), …

a++, a=a; // first increment, then assign

… but this shows the whole leak of meaning of what you want to do.

It is the same with your first example. Though ? is a sequence point …:

The following are the sequence points described in 5.1.2.3:

… The end of the first operand of the following operators: […] conditional ? (6.5.15);[…].

… both the increment (a++) and the assignment (a=) are after the ? operator is evaluated and therefore unsequenced ("in random order") again.

To make the comment "Be careful" more concrete: Don't use an incremented object in an expression twice. (Unless there is a clear sequence point).

int a = 1;
… = a++ * a;

… evaluates to what? 2? 1? Undefined, because the increment can take place after reading a "the second time".

BTW: The Q is not related to Objective-C, but to pure C. There is no Objective-C influence to C in that point. I changed the tagging.

Wang
  • 5
  • 2
Amin Negm-Awad
  • 16,582
  • 3
  • 35
  • 50