0

I want to compare the adjacent characters in a string in a while loop, but the following 2 if statements give me different results.

1st: (this doesn't work)

if (input_str[k] == input_str[++k]) {
    count++;
}

e.g. when k=0 then it should be "if (input_str[0] == input_str[1])"

2nd: (this works)

if (input_str[k++] == input_str[k]) {
    count++;
}

e.g. when k=0 then it should be "if (input_str[0] == input_str[1])"

I guess the safe way will be the following code, but I still want to know why the other two if statement produce different results.

if (input_str[k] == input_str[k + 1]) {
    count++;
}
k++;
user903151
  • 55
  • 1
  • 1
  • 6
  • 6
    "I thought this would work but it does" is an interesting statement.. Anyway, change the title to something meaningful – Eugene Sh. Feb 26 '15 at 19:36
  • 3
    You should read this: [Undefined behavior and sequence points](http://stackoverflow.com/q/4176328/3425536). It should clear your confusion. – Emil Laine Feb 26 '15 at 19:39
  • Why do you think `input_str[k] == input_str[++k]` would evaluate to `input_str[0] == input_str[1]`? – Eugene Sh. Feb 26 '15 at 19:39
  • 4
    because he's a beginner.... and the language is light years away from anything that can be called intuitive. – Karoly Horvath Feb 26 '15 at 19:41
  • 1
    it's nearly impossible to reason when you don't know the "basics" – Karoly Horvath Feb 26 '15 at 19:42
  • 3
    @EugeneSh.: In a language with strict left-to-right evaluation, `input_str[k] == input_str[++k]` would evaluate to `input_str[0] == input_str[1]`. C is not such a language, but how does "reasoning" (as opposed to research, for example) help you deduce that fact? – rici Feb 26 '15 at 19:47
  • 1
    I thought this was a friendly environment to ask questions, and I guess I was wrong. lol – user903151 Feb 26 '15 at 19:49
  • 2
    @user903151: The problem here is that sequence point questions like this (that is, the assumption that evaluation will be left-to-right as opposed to at the whim of the compiler) show up with depressing regularity. I know it is new to you, but even a little bit of research would provide dozens of similar questions, and not just on SO. – rici Feb 26 '15 at 19:51
  • @rici Reasoning can help to justify some "obvious" assumptions (which are not that obvious). And research can help reasoning by providing facts. – Eugene Sh. Feb 26 '15 at 19:51

1 Answers1

4

In all of these cases:

input_str[k] == input_str[++k]
input_str[k++] == input_str[k]
input_str[k] == input_str[k + 1]

the first expression is not guaranteed to be evaluated before the second expression. It can also be evaluated after the second expression.

I.e. when k = 0,

  • input_str[k] == input_str[++k] may be evaluated as input_str[0] == input_str[1] or input_str[1] == input_str[1].
  • input_str[k++] == input_str[k] may be evaluated as input_str[0] == input_str[1] or input_str[0] == input_str[0].
  • input_str[k] == input_str[k + 1] will always be evaluated as input_str[0] == input_str[1].

So in short, you're invoking undefined behavior in the first two cases, and the only safe way is the one with k + 1 and incrementing k afterwards.

See this question for an explanation on why this happens.

Community
  • 1
  • 1
Emil Laine
  • 41,598
  • 9
  • 101
  • 157
  • @user903151 Great, btw edited my answer to be a little more explanatory. – Emil Laine Feb 26 '15 at 20:01
  • It is not just the order of evaluation that matters, but also the order of mutation. IOW, `i[k++] == i[k]` could be compiled to the following partially-ordered statements: `(1)t1 = i[k]; (2)t2 = k + 1; (3)t3=i[k]; (4)result = t1 == t3; (5)k = t2;` The only constraints are that (1) and (3) occur before (4); and (1) and (2) occur before (5). Any other ordering is possible. – rici Feb 26 '15 at 20:04