0

Once I encountered following code:

int s =10;
int *p=&s;
cout << p[3] << endl;

And I can't understand why am I able to access p[3] that doesn't exist (only p exists that is single pointer but I still get access to p[3] that is array that I have never created).

Is it some compiler bug or it is a feature or I don't know some basics of C++ that covers this?

Thank you

5
  • Undefined Behavior is Undefined Behavior. Commented Feb 21, 2016 at 22:02
  • 1
    Code that has bugs will do strange things, so don't write code with bugs. The compiler cannot catch every bug. Commented Feb 21, 2016 at 22:03
  • 1
    There is no array of pointers here. There is a pointer to int being treated as an array of int. This is inherited from C and possibly its predecessors. Commented Feb 21, 2016 at 22:03
  • All this commentary about UB wouldn't apply if the OP had used an index of 0 instead of 3. Commented Feb 21, 2016 at 22:07

4 Answers 4

3

Why does C++ consider pointer and array of pointers as same thing?

It doesn't. You're asking why it treats pointers and arrays as the same.

The [] operator is just an abbreviated form of pointer arithmetic. a[b] is equivalent to *(a + b). Array names can decay into pointers, and then pointer arithmetic is applied. It's the programmers job to make sure they don't go out of bounds. The compiler can't possibly stop you from shooting your foot off.

Also, claiming to be able to "access" it is a strong assertion. That is UB, and is most likely going to either read the wrong memory or get a segfault.

Sign up to request clarification or add additional context in comments.

2 Comments

Just to clarify. Did you meant a[b] equivalent to *(a+lengthof(a)*b)
I got it : ))) you was right. In pointer arithmetic following is true a[5] == 5[a] due to fact that *(a + b)
2

No, it's not a compiler bug, its a very useful feature... but lets not get ahead of ourselves here, the consequence of your code is called Undefined Behaviour

So, what's the feature? All naked arrays are actually pointer to the first element. Except un-decayed arrays (See What is array decaying?).

Consider this code:

int s =10;
int* array = new int[12];

int *p;
p = array; // p refers to the first element
int* x = p + 7; //advances to the 7th element, compiler never checks bounds
int* y = p + 700; //ditto ...this is obviously undefined

p = &s;  //p is now pointing to where s
int* xx = p + 3; //But s is a single element, so Undefined Behaviour

Once an array is decayed, it's simply a pointer... And a pointer can be incremented, decremented, dereferenced, advanced, assigned or reassigned.

So,

cout << p[7] << endl;

is a valid C++ program. but not necessarily correct.

It's the responsibility of the programmer to know whether a pointer points to a single element or an array. but thanks to static analyzers and https://github.com/isocpp/CppCoreGuidelines, things are changing for good.

Also see What are all the common undefined behaviours that a C++ programmer should know about?

Comments

1

From here, section array-to-pointer decay:

There is an implicit conversion from lvalues and rvalues of array type to rvalues of pointer type: it constructs a pointer to the first element of an array. This conversion is used whenever arrays appear in context where arrays are not expected, but pointers are

2 Comments

Apart for the title, you mean?
Well, title and question's content regard somehow different issues, so I can't say you're wrong nor right indeed.
1

Inherited from C, C++ allows you to treat any pointer like the first element of an array starting at that address. That's in part because it passes arrays by reference as pointers and so for that to make sense you need to be able to treat a pointer as an array. It also enables some quite neat and very efficient code in various circumstances.

The upshot is that p[3] is a valid construct in this context. Obviously however it has undefined behaviour because p isn't pointing to an array! Unfortunately the language rules (and compiler) aren't smart enough to work that out. C is a very low level language and doesn't enforce nice things like range checking either during compilation or execution.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.