Re: Validity of pointer conversions
On Jan 5, 6:35 pm, Salt_Peter <pj_h...@yahoo.com> wrote:
On Jan 5, 10:02 am, 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.
// Are you sure? try...
int array[10][5]= {99};
What does that change? You have different initial values
(array[0][0] == 99, all other elements == 0). But there is
still an array bounds violation in the function, which is
undefined behavior.
// and as far as a function for an array:
template< typename T,
const std::size_t Rows,
const std::size_t Columns >
void some_func(T(& arr)[Rows][Columns])
{
// do stuff
}
// this works. guarenteed
std::vector< std::vector< int > > vvn(10, std::vector<int>(5, 99));
That does something different. It initializes all of the
elements with 99, rather than the first with 99, and all of the
others with 0.
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. I think it is guaranteed to work for the same reason
as the first one, that is we can treat an array (sequence)
of integers as various types of integer arrays.
Anything written in C++ that requires a reinterpret_cast
sounds an alarm here. You can only guess at what the result
might be (and possible test/check the result with typeid).
That's not quite true---there are a few things you can do with
reinterpret_cast which have defined behavior. But this isn't
one of them. On the other hand, the expressed intent of
reinterpret_cast in the standard is to support type punning, in
so far as reasonable on the underlying architecture, so from a
quality of implementation point of view, I would expect it to
work on most architectures.
Hacking is not programming. Respect your types at all costs.
Its directive #1, no exceptions.
C++ has reinterpret_cast for a reason. I use it, for example,
when implementing things like malloc or garbage collection. In
such cases, it's a necessary evil.
In anything but such low level (architecture dependent)
programming, of course, it's a guaranteed problem, if only for
reasons of readability.
(For the rest, I very much agree with the part I've cut.
Anything involving reinterpret_cast is a hack, and hacks should
be reserved for the cases where they are absolutely necessary.)
--
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