"puppi" <> wrote in message
news:e953b692-324d-42d3-b35c-...
On Mar 17, 9:48 pm, "Paul" <pchris...@yahoo.co.uk> wrote:
> "Leigh Johnston" <le...@i42.co.uk> wrote in message
>
> news: ...
>
> > On 17/03/2011 23:00, Paul wrote:
>
> <prune>
>
> >>>>> Maybe the following will help you understand the semantic
> >>>>> differences
> >>>>> involved:
>
> >>>>> int main()
> >>>>> {
> >>>>> int* p1 = new int[42]; // 'p1' is a pointer to the first element of
> >>>>> an
> >>>>> array
> >>>>> int (*p2)[42] = new int[1][42]; // 'p2' is a pointer to an array
> >>>>> }
>
> >>>> This is a clear indication of how screwed up you are. Please read the
> >>>> following :
>
> >>>> "the newexpression yields a pointer to the initial element (if any)
> >>>> of the
> >>>> array. [Note: both new int and new int[10] have type int* and the
> >>>> type
> >>>> of new int[i][10] is
> >>>> int (*)[10]. ]"
>
> >>>> The standards define both of these types to be pointers to the array,
> >>>> they are just different *types* of pointer.
>
> >>> No; for the final time: int* is not a pointer to an array; int* is a
> >>> pointer to a scalar; the Standard clearly states "the new-expression
> >>> yields a pointer to the initial element (if any) of the array"; it
> >>> doesn't state that "the new-expression yields a pointer to the array".
>
> >> Err no your nonsense is becoming beyond belief .
> >> A pointer to the first element *IS* a pointer to the array.
>
> >> The standards states clearly that both int* and int(*)[10] are pointers
> >> to the first element. There is no difference in what these pointers
> >> point to. You must think int(*)[10] is an array of pointers or
> >> something
> >> , *shakes head* no I don't know what nonsense you think.
>
> > Yes everything seems like nonsense to you as you are either unable or
> > unwilling to be get a firm technical grasp on C++ matters.
>
> PROVEN WRONG!
The only true difference between "int* p1 = new int[42]" and "int (*p2)
[42] = new int[1][42]" is how offsets are computed. ANSI C (and
Standard C++) implement multidimensional arrays as dope vectors, i.e.
as a long linear array with a polynomial evaluation of offsets, which
causes it to act as a multidimensional array. A call such as "new
int[2][42]" would truly return the address of the first element of a
2*42=84 int elements array. They are the same thing at the machine
level. They differ only in how the compiler computes offsets. If n is
an integer type, an expression such as "p1+n" evaluates as the address
in p1 plus n*sizeof(int), while an expression such as "p2+n" evaluates
as the address in p2 plus n*sizeof(int[42]) == 42*n*sizeof(int). An
expression such as "p2[n][m]" evaluates as the address in p2 plus
42*n*sizeof(int)+m*sizeof(int). The following code illustrates that,
where I changed the definition of p2 to "new int[2][42]" for further
explanations:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxx
Exactly, the only difference is how the compiler computes the offsets.
And, BTW, nobody in their right mind is ever going to use a type such as
int(*)[64] anyway.
Sorry my auto indentation is not working for this message.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxx
#include <cstddef>
#include <cassert>
int main()
{
volatile int *p1 = new int[42];
volatile int (*p2)[42] = new int[2][42];
//follow the generated assembly code from here...
asm volatile
(
"nop;\nnop;"
);
p1[2];
asm volatile
(
"nop;\nnop;"
);
p2[0][-1];
asm volatile
(
"nop;\nnop;"
);
//...to here
assert(&p2[1][-1] == &(*p2)[41]);
asm volatile
(
"nop;\nnop;"
);
volatile int *p3 = (int*)p2;
assert(p3+42 == (int*)(p2+1));
for(size_t i = 0; i < 42; i++)
assert(&p3[i] == &p2[0][i]);
for(size_t i = 0; i < 42; i++)
assert(&p3[42+i] == &p2[1][i]);
asm volatile
(
"nop;\nnop;"
);
return 0;
}
If you know your assembly, you should follow how access is made for p1
and p2. You will see it's identical. In my pc generated the following
code fragment for the first part (where p1 was stored in rbp-0x8 and
p2 in rbp-0x10):
movq -8(%rbp), %rax
addq $8, %rax
movl (%rax), %eax
nop;
nop;
movq -16(%rbp), %rax
movl -4(%rax), %eax
It's simply the same. I declared the pointers volatile simply to
prevent the compiler from "weeding out" parts of my code with no
possible side-effects. Only the line "&p2[1][-1] == &(*p2)[41]" may
not work under all compilers. It will work if and only if
sizeof(size_t)==sizeof(void*).
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxxx
Yes the pointer-type does not affect what it points to in this case. The
only difference is pointer arithmetic in the case of..
int p(*)[size]
1 = sizeof(int) * size.
Not too difficult to understand is it .