Undefined Behavior of c/c++

After a long time I was back to C/C++ programming and was designing a simple data structure and found some strange output in my results, thinking it must be a fault from my side. After spending some time tracing the fault I couldn't find anything and tried the code on another machine. But it still showed the same results. Something triggered my brain and I started investigating on my global array.

To make sure the problem was the array, I wrote a simple program on global array and to my surprise it did show this unexcpected behavior. The code is:

#include
using namespace std;
int weird[2];
int main(){
for(int i=0;i<100;i++)
weird[i]=i;
for(int i=0;i<100;i++)
cout << weird[i] << " ";
return 0;
}

After compiling the code, the output was something like this:


output-screenshot

After this I started searching this over internet but didn't find much. But at last I found a amazing answer on StackOverflow about this. The link to answer is here.


What is this Undefined Behavior?

The language simply says what should happen if you access the elements within the bounds of an array. It is left undefined what happens if you go out of bounds. It might seem to work today, on your compiler, but it is not legal C or C++, and there is no guarantee that it'll still work the next time you run the program. Or that it hasn't overwritten essential data even now, and you just haven't encountered the problems, that it is going to cause — yet.

As for why there is no bounds checking, there are a couple aspects to the answer:

  • An array is a leftover from C. C arrays are about as primitive as you can get. Just a sequence of elements with contiguous addresses. There is no bounds checking because it is simply exposing raw memory. Implementing a robust bounds-checking mechanism would have been almost impossible in C.

  •  In C++, bounds-checking is possible on class types. But an array is still the plain old C-compatible one. It is not a class. Further, C++ is also built on another rule which makes bounds-checking non-ideal. The C++ guiding principle is "you don't pay for what you don't use". If your code is correct, you don't need bounds-checking, and you shouldn't be forced to pay for the overhead of runtime bounds-checking.

  • So C++ offers the std::vector class template, which allows both. operator[] is designed to be efficient. The language standard does not require that it performs bounds checking (although it does not forbid it either). A vector also has the at() member function which is guaranteed to perform bounds-checking. So in C++, you get the best of both worlds if you use a vector. You get array-like performance without bounds-checking, and you get the ability to use bounds-checked access when you want it.
Suhaib Bin Younis | @suhaibbinyounis

Post a Comment

Post a Comment (0)

Previous Post Next Post