1

I made this code

#include <stdio.h>

int main(void)
{
    int i = 0;
    int arr[20];
    while(i < 20)
    {
         arr[i++] = i;
         printf("%d\n", arr[i-1]);
    }
    return 0;
}

which seems to print the results expected why it is said you can have undefined behavior?

Kevin
  • 1,151
  • 1
  • 10
  • 18
  • 1
    You have undefined behavior - so you *may* get the value that you want, or you *may not.* Just because you *get* the expected values does not mean that the code is correct and well defined. – abhishek_naik May 24 '16 at 02:24
  • How i can check the undefined behavior – Kevin May 24 '16 at 02:27
  • Run the above code on a different compiler. – abhishek_naik May 24 '16 at 02:27
  • I tried three compilers but I get the same output – Kevin May 24 '16 at 02:29
  • undefined behavior means nothing is guaranteed to work. Anything can happen, including [a nasal demon flying out of your nose](http://www.catb.org/jargon/html/N/nasal-demons.html), [Does “Undefined Behavior” really permit *anything* to happen?](http://stackoverflow.com/q/32132574/995714) – phuclv May 24 '16 at 04:50
  • Try it on different optimization levels as well. – user253751 May 24 '16 at 04:59
  • It's also quite possible that all compilers in the world compile it the way you expect, but tomorrow someone will write one that doesn't, and it won't be the compiler that's considered broken. – user253751 May 24 '16 at 04:59

3 Answers3

2

You are invoking undefined behavior. You have made use of sequence points, usage of which is undefined in C.

You say it seems to print the results expected - it may or it may not, because it is undefined. So the fact that you get the expected values is just pure luck.

As for getting some warnings, please compile and run the code; it will indeed give you a warning:

warning: operation on 'i' may be undefined [-Wsequence-point]

Live demo here.

Besides, if you are thinking why it is just a warning and not an error, then please note that the compiler is in no way bound to report all of your undefined behaviors - its job is just to compile your code, not to point out your undefined behavior.

Community
  • 1
  • 1
abhishek_naik
  • 1,287
  • 2
  • 15
  • 27
  • 1
    To be ridiculously pendantic, all "undefined behavior" means is that the compiler isn't *required* to handle the erroneous code in any particular way; it *may* issue a diagnostic and halt translation (error), it *may* issue a diagnostic and complete translation (warning), it *may* complete translation without a diagnostic. If it completes translation, the generated machine code *may* terminate with a runtime error, it *may* run to completion with no apparent issues, it *may* launch Rogue. As far as the standard is concerned, *all* of those outcomes are equally "correct". – John Bode May 24 '16 at 16:12
  • @JohnBode, I totally agree. – abhishek_naik May 24 '16 at 18:49
1

Depending on the evaluation order, the first time execution of

     arr[i++] = i;

could end up setting arr[1] to 1 (if the LHS is evaluated first) or to 0 (if the RHS is evaluated first). If they are executed in parallel, the result could be anything.

We cannot guarantee the state of the program after that line. Don't use it.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
1

"It works as expected" is one of the possible outcomes for undefined behavior.

arr[i++] = i; is explicitly called out as an example of undefined behavior in the language standard. The order in which each subexpression is evaluated is unspecified; it's not guaranteed to be left-to-right. For i == 1, any of the following results are possible:

arr[1] = 1;
arr[1] = 2; 
arr[2] = 2; 
arr[2] = 1;
John Bode
  • 119,563
  • 19
  • 122
  • 198