-1

sir would you please tell me that why the following condition in 'C' is false?

main()
{
    int i=1;
    if(i<=i++)
        printf("false");
    else
        printf("true");
}
Diosney
  • 10,520
  • 15
  • 66
  • 111
  • 3
    Please do not write code like this `if(i<=i++)`. Separate the two operations into two separate lines. Will make your life easier in the long run. – Ed Heal Aug 30 '13 at 01:50
  • 2
    As @Sancho writes in his answer, this is undefined behavior. There is a special place in C programmer hell for people who think this is OK, please don't write code like this. :-) – asveikau Aug 30 '13 at 02:24
  • @user2731283, please review my answer, if it helps you understand then please accept it as an answer. My peers are dancing on the head of a pin and do **NOT** understand how to explain a simple concept to a new programmer!! – JackCColeman Aug 30 '13 at 03:35
  • @JackCColeman Undefined behaviour is not pin-dancing. Sometimes, your code will actually behave differently from the top code. Worse from an explanatory point of view, it will behave differently in exactly the way the OP was asking about, making a true condition false. – 1'' Aug 30 '13 at 14:35
  • possible duplicate of [Undefined Behavior and Sequence Points](http://stackoverflow.com/questions/4176328/undefined-behavior-and-sequence-points) – amalloy Aug 30 '13 at 18:54
  • 1
    @1", my point was that the person asking the question is a new programmer and topics like sequence points become noise when the new programmer is still figuring out if and ++ operators. We should tailor our answers to the experience level of the asker! – JackCColeman Aug 30 '13 at 18:55

4 Answers4

12

It's not false, you just print false when it's true.

Paul
  • 139,544
  • 27
  • 275
  • 264
  • Still points out an error that'll be there even after the poster deals with the UB though. – Dennis Meng Aug 30 '13 at 01:53
  • 8
    @Paulpro: It is undefined behavior. Accessing and separately modifying an object without an intervening sequence point has undefined behavior, per C 2011 (N1570) 6.5 2. – Eric Postpischil Aug 30 '13 at 01:58
3

The comparison operator <= doesn't specify which side will be evaluated first, the i or the i++, and there is no sequence point at the end of the left-hand operand to a comparison function (see http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Sequence-Points).

If the left side is evaluated first, you get:

if (1 <= 1)

If the right side is evaluated first, you get:

if (2 <= 1)

This highlights the problem, but it's even worse than that.

You have written code with undefined behaviour, which means exactly that, "undefined". The compiler can do anything in this case and still be compliant with the standard.


For example, these compilers (with -O3) follow the else branch:

While these compilers (with -O3) follow the true branch:

And other compilers could do something completely different.

  • Even if it works but it is hard to understand. Some person in a years time (even maybe yourself) have to figure out what is exactly the line of code is doing. Therein lies a lot of problems. Why cannot people that is easy to read and understand? Job security is the only explanation for not writing easy to read code I feel – Ed Heal Aug 30 '13 at 02:56
  • @Sancho, it may be undefined, (I don't agree or disagree on this point), but it can be reasonable. Why would the person who wrote the compiler be unreasonable, supercilious or otherwise nasty? – JackCColeman Aug 30 '13 at 18:16
  • @JackCColeman You don't agree that it is undefined behaviour? Yes, the resulting behaviour *can* be reasonable, but that is not guaranteed. –  Aug 30 '13 at 18:26
  • @JackCColeman About why the compiler designers may choose to let undefined behaviour result in things you would find unreasonable, etc. see [here](http://blog.regehr.org/archives/213), [here](http://blog.llvm.org/2011/05/what-every-c-programmer-should-know.html), and especially [here](http://blog.regehr.org/archives/759). In the opinion of that author, "*the compiler isn’t going to go out of its way to make undefined executions behave badly. It just doesn’t care about them.*" –  Aug 30 '13 at 18:30
  • @Sancho, what I agree with is writing code that does **NOT** fall into the category of undefined behavior. Explicit well-written code functions as written. New programmers need to learn to recognize ambiguous code. – JackCColeman Aug 30 '13 at 19:23
  • The behavior is unspecified as well as undefined, it may seem like a subtle difference but they are different. – Shafik Yaghmour Aug 31 '13 at 23:47
  • 1
    @ShafikYaghmour Ya it's both. –  Sep 01 '13 at 00:50
1

This is a combination unspecified behavior and just plain and simple undefined behavior. So you can not predict the outcome of this code and the results can not be relied on. It is unspecified because in this line:

if(i<=i++)

we do not know whether the i or the i++ will be evaluated first. The draft C99 standard section 6.5 paragraph 3 says:

The grouping of operators and operands is indicated by the syntax.74) Except as specified later (for the function-call (), &&, ||, ?:, and comma operators), the order of evaluation of subexpressions and the order in which side effects take place are both unspecified.

The above mentioned line also is undefined behavior because between sequence points we are only allowed to modify a variable once and if we modify it we are only allowed to read the previous value to determine the new value to set. In this case we are reading the prior value to determine both i and i++. From the draft standard section 6.5 paragraph 2:

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.

Shafik Yaghmour
  • 154,301
  • 39
  • 440
  • 740
-3

To understand what your code is doing, I am going to re-write, only will be VERY explicit:

main()
{
    int i=1;
    if(i<=i) {
        i++;
        printf("false");
    } else {
        i++:
        printf("true");
    }
}

The i++ means to increment i after the comparison. In both branches of the if i is being incremented, so it is equivalent.

JackCColeman
  • 3,777
  • 1
  • 15
  • 21
  • This code is meant to explain, NOT be an example of good coding. Whoever down voted my answer does not understand what I am trying to demonstrate. – JackCColeman Aug 30 '13 at 01:59
  • 7
    I downvoted because you can't guarantee that the ordering you chose (left side of the `<=` being evaluated before the right side of the `<=`) will be the ordering the compiler uses. –  Aug 30 '13 at 02:00
  • 8
    In `i <= i++`, the C standard permits the implementation to increment `i` either before or after taking the value of `i` for the left side of `<=`. Additionally, this means that `i` may be both modified and separately used without an intervening sequence point, which has undefined behavior. – Eric Postpischil Aug 30 '13 at 02:05
  • 5
    `i++` doesn't mean increment *after* the comparison. It means increment `i` and and return the value it had prior to the increment. –  Aug 30 '13 at 02:05
  • 4
    This answer is wrong, because the original undefined behaviour is not equivalent to the defined behaviour in the answer. – 1'' Aug 30 '13 at 02:49
  • I'm willing to bet the student will learn something with this description. – JackCColeman Aug 30 '13 at 03:33