-2
int main()
{
    int c=5;
    printf("%d\n%d\n%d", c, c<<=2, c>>=2);
    return 0;
}

I am not getting how the assignment is taking place in the printf function. The output is coming out to be 4,4,4 but according to me it should be 4,4,1.

Tom Zych
  • 13,329
  • 9
  • 36
  • 53
Ayesha Gupta
  • 145
  • 4
  • 13
  • and according to the standard, it's undefined behavior. it seems that you expect that function arguments are evaluated left-to-right. They may or may not be. – The Paramagnetic Croissant Jul 04 '14 at 11:26
  • You should add the correct language tag to your question [tag:c] or [tag:c++] – Sayse Jul 04 '14 at 11:27
  • @Sayse This clearly is C, not C++. – The Paramagnetic Croissant Jul 04 '14 at 11:27
  • @user3477950 - I haven't written in either for well over a year, I couldn't remember syntax – Sayse Jul 04 '14 at 11:28
  • Maybe even better: http://stackoverflow.com/questions/949433/why-are-these-constructs-undefined-behavior – Deduplicator Jul 04 '14 at 12:14
  • @user3477950 C would use `int main(void)`, C++ could use `int main()`. `printf()` is in both languages. – chux - Reinstate Monica Jul 04 '14 at 19:16
  • @chux `int main()` is equally valid C, it's just that it doesn't mean `int main(void)`. `printf()` does not work in C++ without an additional `std::` namespace qualification (at least not when ones the only non-obsolescent header file containing it, which is ``). – The Paramagnetic Croissant Jul 04 '14 at 19:18
  • @user3477950 C11 §5.1.2.2.2 _Program startup_ does not agree with "`int main()` is equally valid C". – chux - Reinstate Monica Jul 04 '14 at 19:20
  • @chux Actually, it does so perfectly. If the controlling environment calls `main` as if it took no parameters, then it's equivalent with `int main(void)`. If it calls it as if it was declared as `int main(int, char **)`, then it's equivalent with that. *In any other case, the "or in some other implementation-defined manner" clause takes place* and we're back at my previous comment. (BTW, 5.1.2.2.2 is not "program startup", rather section 5.1.2.2.1 is.) – The Paramagnetic Croissant Jul 04 '14 at 19:25

2 Answers2

3

There are no sequence points between your modifications of c and so the behaviour is undefined.

You need to impose sequence explicitly. For example:

int main(void)
{
     int c = 5;
     int d = c >> 2;
     int e = d << 2;
     printf("%d\n%d\n%d", c, e, d);
     return 0;
}

You should, as a matter of course, ask your compiler to report warnings. If you do so, and assuming that your compiler is competent, then it will warn you of the issue. For instance, my GCC when asked to compile your program using the -Wall option reports:

main.c: In function 'main':
main.c:6:37: warning: operation on 'c' may be undefined [-Wsequence-point]
     printf("%d\n%d\n%d", c, c<<=2, c>>=2);
                                     ^
main.c:6:37: warning: operation on 'c' may be undefined [-Wsequence-point]
David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
1

You should use -Wall flag when compiling.

I got:

../main.c:6:37: warning: operation on ‘c’ may be undefined [-Wsequence-point]
../main.c:6:37: warning: operation on ‘c’ may be undefined [-Wsequence-point]

This code for example is broken:

c<<=2

since There are no sequence points between your modifications of c.

It should be something like this:

int a = c << 2;

As a result, your code leads to undefined behaviour.

gsamaras
  • 71,951
  • 46
  • 188
  • 305
  • @Deduplicator I updated my answer, taking something from the other answer, since the other answer obviously got my warnings (but that's nice, because it's better). :) – gsamaras Jul 04 '14 at 12:50