Click here to Skip to main content
15,867,453 members
Please Sign up or sign in to vote.
1.00/5 (2 votes)
See more:
Previously I was asked this question and was not sure about the exact answer to give,
imagine I have:

C++
(&x-99)[2]


The question was, where would it point?
My initial explanation was that since we don't know in which memory region &x-99 will end up,
the compiler/program might not know exactly, how many bytes from it, to move forward by looking at [2].
Was I right? e.g., if we add 1 to a int pointer, it will move say 4 bytes forward, if we add 1 to char pointer it will move one byte forward, ...


ps. I see nobody understood my question here correctly. I was saying, say there is y[2] (y is int).
Now, how does compiler calculate offset? it takes probably type of y and adds to it 8(8=4*2)
right? (due to size of int). Now in this case: (&x-99)[2]. My question was, what will be the offset here? How many bytes should compiler take and multiply on 2? In previous case it checked type of y, but in this case, how does it know which type (&x-99) corresponds to? Did I make it clear now?
Posted
Updated 15-Sep-13 19:28pm
v3
Comments
pasztorpisti 15-Sep-13 17:05pm    
Pointer arithmetic is very similar to array indexing. The following lines evaluate to the same:
(&x-99)[2]
(&x)[-99+2]
(&x-99+2)[0]
*(&x-99+2)
Stefan_Lang 16-Sep-13 6:30am    
And you might add:

2[&x-99]

which is valid C/C++ syntax, too!
Maybe even the following works, but I'm unsure about the neg value:

(-99)[&x+2]
pasztorpisti 16-Sep-13 6:41am    
I've almost forgot this syntax. :-) I'm afraid we confuse OP with it. For some reason I never liked it, C probably inherited this from assembly. It's generally bad when you can do the same thing in many different ways. (This is already at least 3 ways to index into an array with a pointer.)
_coder 16-Sep-13 6:45am    
please see my edit
pasztorpisti 16-Sep-13 7:01am    
Expression: a(&x+b)[c] where a, b and c are integer constants (a==0, b==-99, c==2). The offset in bytes relative to &x is sizeof(x) * (a+b+c) == 4 * -97
Yes, it is a negative offset.

Try this code:
C++
#include <iostream>
#include <vector>
using namespace std;

int main()
{
    int x[1000];
    int (*p)[1000] = &x-99;
    cout << x << ", " << p << ", " << p[2] << endl;
    cout << (int)(&x-p)<< ", " << (int)(x-p[2]) << endl;
}



output on my system:
C++
019DEDC0, 0197E2E0, 01980220
99, 97000 
 
Share this answer
 
Comments
_coder 14-Sep-13 16:49pm    
What is int (*p)[1000] ?? Is it array if pointers? Have never seen it. Anyway, I think I didn't get your point. Btw. I did some tests. Like here:

int x = 12;
cout<<&x<<endl;
cout<<(&x-188); // prints exactly 4x188 bytes behind address of x
cout<<&((&x-188)[1]); // Prints exactly 4 byes AFTER above address

It seems to work Ok for an int type. But I was curious about cases, when &x-188 refers to a memory address - from which, and using [1] the program does not know how many bytes to move forward... am I making it clear?
CPallini 14-Sep-13 17:01pm    
it is a pointer to an array of integers (the same type of (&x-99)).
_coder 14-Sep-13 17:16pm    
honestly, I didn't get the point of your example. so like you wanted to show p[2] started pointing to an address very far from p?
CPallini 14-Sep-13 17:32pm    
My point is (&x-99) should be interpreted as a pointer to an array of integers. As such, if the array size is big enough, it is very far away from x.
_coder 15-Sep-13 6:28am    
I think you still didn't get my point. Let's say I have y[2] - how does the compiler know correctly how many bytes it should offset by looking at [2]?? Probably it would check type of y, say int, and y[2] would be 8 (8=4*2) bytes further address of y, right? My question was how does the compiler know how many bytes further from (&x-99) to move when it looks at expression (&x-99)[2]?? 4 bytes? 8? or maybe 2?
C++ is strongly typed language. Your example is simple case of pointer arithmetic. "99" will be multiplied by number of bytes of size of type "x". To illustrate, here is an example:

C#
int main()
{
int arri[10] = {0,1,2,3,4,5,6,7,8,9};
char arrc[10] = {'0','1','2','3','4','5','6','7','8','9'};

std::cout << "Int ptr:" << (&arri[0] + 1)[2] << "\n";
std::cout << "Char ptr:" << (&arrc[0] + 1)[2] << "\n";
return 0;
}
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900