2
#include<stdio.h>
 int main(){

     int arr[ 5 ] = { 1, 2, 3, 4, 5 };

     int *f = arr;

     int *l = (4+arr);

     while(f<l){

       *f^=*l^=*f^=*l; 

       ++f; --l;  
}

printf("\n%d\t%d\t%d\n", *arr, *f, *l)

return 0;

}

My output is 1 3 3 on paper but compiler is showing 033. Please anyone explain it to me. Thanks in advance.

Jens
  • 69,818
  • 15
  • 125
  • 179
d4deepak
  • 35
  • 8
  • 1) Code doesn't compile 2) That `printf` will most likely print whatever happened to be on the stack when you called it. It will most probably be different after you recompile it. – user4520 May 26 '15 at 12:18
  • i have passed these arguments and it is supposed to print 1 3 3 but it is printing 0 3 3 – d4deepak May 26 '15 at 12:19
  • Before C11 assignments weren't [sequenced](http://en.cppreference.com/w/c/language/eval_order) at all, so that big compound assignment in the loop is probably undefined behavior unless you use a C11 compiler, and even then I'm not sure. – Some programmer dude May 26 '15 at 12:28
  • 1
    0 3 3 is correct. Maybe the paper is "bugged" – LPs May 26 '15 at 12:28
  • *f^=*l^=*f^=*l; can you elaborate this – d4deepak May 26 '15 at 12:38
  • 1
    @JoachimPileborg The evaluation of the operands of the assignment operators is not sequenced against each other, even though the assignment is sequenced after those evaluations. ([I just answered a question about that so I have checked the standard](http://stackoverflow.com/questions/30457904/c-operator-sequence-point/30458028#30458028)). Meaning if the same variable occur twice in the expression, the behavior is undefined. – Lundin May 26 '15 at 12:39

3 Answers3

4
*f^=*l^=*f^=*l; 

The evaluation of the operands of ^= is not sequenced, and you use the same variables several times in the same expression, with no sequence point in between.

This means that the behavior of the program is undefined. Nobody can know how that expression will be evaluated and anything can happen. The program may crash or the output can be anything.

You have to fix this bug by changing the code into this:

*f ^= *l;
*l ^= *f;
*f ^= *l;

Then each semi-colon will introduce a sequence point and there are no order of evaluation issues.

Standard references.

Community
  • 1
  • 1
Lundin
  • 195,001
  • 40
  • 254
  • 396
1

I actually don't care one bit how this is evaluated. If you have code and ask "what exactly does this code do", then the correct answer is "don't write that kind of code". (Except if you are writing a compiler, in which case the answer is "you shouldn't be writing compilers if you ask on stack overflow how some code should be executed").

In addition, the result is undefined behaviour in C, C++ before C++ 11, and Objective-C, so that's a good reason not to do it where it is defined. In addition, it has zero chance to pass any code review, and there is a rule "always assume that the next maintenance programmer reading your code is a violent sociopath who knows your home address".

gnasher729
  • 51,477
  • 5
  • 75
  • 98
0

The output is correct:

*arr = ((1^5)^1)^5);

which indeed is 0. Note that *arr is modified during the first iteration and that's all you worry about. In the second and later iterations you're not modifying *arr anymore. At that point f has been updated and doesn't point to arr anymore

A few lines explaining the maths:

  1. 1^5 = 4
  2. 4^1 = 5
  3. 5^5 = 0

EDIT:

I assumed that the language guarantees that the order of evaluation is from left to right. As pointed out by Lundin this is not the case. However, judging by the output of the executable that's most likely the way that the compiler has handled it.

banach-space
  • 1,781
  • 1
  • 12
  • 27
  • 1
    The result of `*f^=*l^=*f^=*l;` is undefined behavior, so there is no expected output: anything can happen. – Lundin May 26 '15 at 12:41
  • Fair enough. Consider my answer then as a comment that what **I** get on paper. – banach-space May 26 '15 at 12:43
  • 1
    You get an expected result because you expect the program to behave in a way which is not guaranteed. If C guaranteed that the order of evaluation of operands must be right to left, and that each assignment in that expression is done and saved before the next calculation, then you could calculate this in advance. Unfortunately, C guarantees neither the order of evaluation nor that the processing of the calculations is done in a certain sequence. – Lundin May 26 '15 at 12:50