0

I'd like a formal explanation on the stance of visual studio C++ and what it does when you create an array such as:

int a[3] = {1, 2, 3};

and you then do something like:

cout << a[4];

Upon test, it will print out the garbage stored in that memory location. Why does it allow the programmer to do this, while a language like javaScript will prevent the user from doing so?

What's the prevailing philosophy by not making the compiler ban this kind of behavior from the user in C++? Is this something carried over from C?

These are just some minor curiosities that I have, and perhaps the person who answers can tell me where I'd be able to find such information. The answer as to what is happening is not what I'm asking, it's the why that I'm interested in.

Thank you.

zeromus
  • 1,648
  • 13
  • 14
user3499524
  • 173
  • 9
  • why do you use the javascript tag? – Nina Scholz Apr 25 '16 at 07:24
  • @NinaScholz Because I mention javascript in my comment. Not sure if you saw that. I was thinking, maybe I'll also get a javaScript explanation too. Regardless, I removed the tag because zeromus sort of requested me in doing so. – user3499524 Apr 25 '16 at 07:37
  • 1
    The philosophy is not paying for what you don't use. That is to say, not imposing the costs of bounds checking on the developer - rather assuming the developer has already made such checks if he thinks he needs them. Such checking *is* included in standard library constructs like std::array and std::vector, or rather can be configured to have them in either debug or release builds. – Robinson Apr 25 '16 at 07:41
  • 1
    in javascript you get simply an `undefined` for indices which are not initialized. – Nina Scholz Apr 25 '16 at 07:45

1 Answers1

2

It has nothing to do with the compiler, but the language is defined in such a way that it's allowed. It will lead to undefined behavior though as the contents is indeterminate.

As for the reason it's allowed, consider the definition of the subscript (array indexing) operator (From ISO/IEC 14882:2011(E) §5.2.1/1 [expr.sub]):

A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall have the type “pointer to T” and the other shall have unscoped enumeration or integral type. The result is an lvalue of type “T.” The type “T” shall be a completely-defined object type. The expression E1[E2] is identical (by definition) to *((E1)+(E2))

[Emphasis mine]

What happens due to the above is that the array E1 is decayed to a pointer to the first element (i.e. it's equivalent to &(E1)[0]), and then the compiler performs pointer arithmetic with (E1)+(E2). And since the array has decayed to a pointer, there is no possibility for bounds-checking.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621