Re: Validity of pointer conversions
On Jan 5, 10:02 pm, Ioannis Vranos <j...@no.spam> wrote:
James Kanze wrote:
On Jan 5, 4:02 pm, Ioannis Vranos <j...@no.spam> wrote:
Are the following codes guaranteed to work always?
1.
#include <iostream>
inline void some_func(int *p, const std::size_t SIZE)
{
using namespace std;
for(size_t i=0; i<SIZE; ++i)
cout<< p[i]<< " ";
}
int main()
{
int array[10][5]= {0};
some_func(array[0], sizeof(array)/sizeof(**array));
std::cout<< std::endl;
}
The above prints 50 zeros. I think it is guaranteed to work,
since all arrays are sequences of their elements.
And? I don't see any relationship between what you just said
and any guarantee of working. You have an array bounds
violation, which is undeefined behavior. And there have been
(and maybe still are) implementations which detect it, and
treat it as an error condition.
What exact array bounds violation is there in the code above?
"int array[10][5];" is a sequence of 50 integers.
No. "int array[10][5]" is an array[10] of array[5] of int. The
standard may require that it be physically laid out as a
sequence of 50 integers, but that has nothing to do with the
type. The type is "int [10][5]". When it decays to a
pointer, the type is "int (*)[5]", a pointer to the first of
ten elements, and when you dereference said pointer, the result
is an int*, pointer to the first of five elements.
The authors of the C standard went out of there way to ensure
that an implementation which tracked bounds would be legal.
2.
#include <iostream>
int main()
{
using namespace std;
int array[50]= {0};
int (*p)[5]= reinterpret_cast<int (*)[5]> (&array[0]);
for (size_t i= 0; i< 10; ++i)
for(size_t j=0; j<5; ++j)
cout<< p[i][j]<<" ";
cout<< endl;
}
Here p behaves as a 2-dimensional matrix, that is a 10x5
matrix.
Almost nothing involving reinterpret_cast is guaranteed to work.
OK, consider int (*p)[5]= static_cast<int (*)[5]> (static_cast<void
*>(&array[0])); instead.
If by that you mean that you can play games with the dimensions,
as long as the total number of elements is unchanged, that is
simply false.
Why?
The short answer is because the standard says so. The rationale
behind this is to allow bounds checking implementations. Such
implementations have existed, and may still exist. (Centerline
offered one, and I believe that the Centerline compiler is still
on the market.)
In all cases we have the same sequence of ints,
So? What does physical layout have to do with type?
that is int array[50], int array[10][5], int array[5][10] are
all implemented as the same sequence of 50 ints. If they are
not implemented in the same way, where do they differ?
The underlying physical layout may be the same, but that doesn't
mean that they have the same type.
--
James Kanze (GABI Software) email:james.kanze@gmail.com
Conseils en informatique orient=E9e objet/
Beratung in objektorientierter Datenverarbeitung
9 place S=E9mard, 78210 St.-Cyr-l'=C9cole, France, +33 (0)1 30 23 00 34