question regarding pointers

  • Thread starter Thread starter Wajih-ur-Rehman
  • Start date Start date
W

Wajih-ur-Rehman

The question is about C++ (since its the C family, i posted it on this
newsgroup)

Lets say i declare an array
int a[] = {1,2,3,4};
int *p = a; //This is allowed because "a" returns the address of the first
element

The question is actually about 2D arrays. As far as I know, when a 2D array
is declared in C++, in the memory it is actually stored as a 1D array. and
the name of the array is pointing to the first element ie. a[0][0] i.e

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

Now the question is that why cant i do this
int *p = a; //Compiler gives error. Whats wrong with this????? a is not an
int ** right?

However following are correct
int *p = &a[0];
int *p = &a[0][0];

Why doesnt int* p = a; work? (if you cout<<a<<&a[0]<<&a[0][0]; it gives the
same address)

Thanx in advance
 
The question is about C++ (since its the C family, i posted it on this
newsgroup)

I suggest you repost in microsoft.public.dotnet.languages.vc



Mattias
 
Hi Wajih-ur-Rehman,

"> The question is actually about 2D arrays. As far as I know, when a 2D
array
is declared in C++, in the memory it is actually stored as a 1D array. and
the name of the array is pointing to the first element ie. a[0][0] i.e

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

Now the question is that why cant i do this
int *p = a; //Compiler gives error. Whats wrong with this????? a is not an
int ** right?

No it is not.
Actually multidimensional arrays are treated differently when they has been
defined statically. They are array of arrays of arrays......
But it is not int** because no pointers are saved so it is not int **.

So when you do a[0] it returns one-dimensional array for the first row,
which can be cast to int *
However following are correct
int *p = &a[0];
This will fail (check it). a[0] is onedimensional array and it is already
pointer to the first element.
So what a[0] returns is address (number, constant) you cannot get the
address of a number. You can get address only of *l-values* (varaibles)
the correct is:
int *p = a[0];

Unlike a[0], which is not a *l-value* a[0][0] is a normal *l-value* and you
can get its address. So the following succeed.
int *p = &a[0][0];
This is ok. a[0][0] returns a *l-value* of the first element and &a[0][0]
returns its address
Why doesnt int* p = a; work? (if you cout<<a<<&a[0]<<&a[0][0]; it gives the
same address)

It shouldn't work. you cannot get &a[0]. However VC++ compiles it and just
change the type of the returning address. now it is of type int (*)[2] which
means pointer that points to array of 2 int values.
I don't know if it is by C/C++ spec and frankly I don't believe it.
Sometimes designers of the compilers simplify the grammer in order to make
it simple and the compiler faster. This simplifications lead to some really
rear erronous constructs to go thru and compiler may not report error at all
or may report not correct error.

So I believe:
int **b = &a[0] ;
should be reported as the error "'&' requires l-value";

Indexing operator [] works differently for multidimensional arrays when they
are declared statically and dynamically:
int a[2][2]
or
int **a;

And here comes the confusion for the compiler:
This definitely doesn work:

int a = 10
int **b = &(&a);
....
compiler says correctly: *& requires l-value*

So if cout <<&a[0]; goes thru that means a[0] is l-value;
Then the following has to work as well:
int a[2][2] = {...}
int b[2] = {...}
a[0] = b;

MS VC compiler reports error: '=' : left operand must be l-value

so a[0] *is not* a l-value;

Can you see the inconsistency here.

I believe you will get different results with different compiler.

HTH
B\rgds
100
 
Hi Wajih-ur-Rehman,

"> The question is actually about 2D arrays. As far as I know, when a 2D
array
is declared in C++, in the memory it is actually stored as a 1D array. and
the name of the array is pointing to the first element ie. a[0][0] i.e

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

Now the question is that why cant i do this
int *p = a; //Compiler gives error. Whats wrong with this????? a is not an
int ** right?

No it is not.
Actually multidimensional arrays are treated differently when they has been
defined statically. They are array of arrays of arrays......
But it is not int** because no pointers are saved so it is not int **.

So when you do a[0] it returns one-dimensional array for the first row,
which can be cast to int *
However following are correct
int *p = &a[0];
This will fail (check it). a[0] is onedimensional array and it is already
pointer to the first element.
So what a[0] returns is address (number, constant) you cannot get the
address of a number. You can get address only of *l-values* (varaibles)
the correct is:
int *p = a[0];

Unlike a[0], which is not a *l-value* a[0][0] is a normal *l-value* and you
can get its address. So the following succeed.
int *p = &a[0][0];
This is ok. a[0][0] returns a *l-value* of the first element and &a[0][0]
returns its address
Why doesnt int* p = a; work? (if you cout<<a<<&a[0]<<&a[0][0]; it gives the
same address)

It shouldn't work. you cannot get &a[0]. However VC++ compiles it and just
change the type of the returning address. now it is of type int (*)[2] which
means pointer that points to array of 2 int values.
I don't know if it is by C/C++ spec and frankly I don't believe it.
Sometimes designers of the compilers simplify the grammer in order to make
it simple and the compiler faster. This simplifications lead to some really
rear erronous constructs to go thru and compiler may not report error at all
or may report not correct error.

So I believe:
int **b = &a[0] ;
should be reported as the error "'&' requires l-value";

Indexing operator [] works differently for multidimensional arrays when they
are declared statically and dynamically:
int a[2][2]
or
int **a;

And here comes the confusion for the compiler:
This definitely doesn work:

int a = 10
int **b = &(&a);
....
compiler says correctly: *& requires l-value*

So if cout <<&a[0]; goes thru that means a[0] is l-value;
Then the following has to work as well:
int a[2][2] = {...}
int b[2] = {...}
a[0] = b;

MS VC compiler reports error: '=' : left operand must be l-value

so a[0] *is not* a l-value;

Can you see the inconsistency here.

I believe you will get different results with different compiler.

HTH
B\rgds
100
 
Back
Top