On 4 Nov, 13:43, "Daniel T." <danie...@earthlink.net> wrote:
> In article
> <f3dab86c-491a-441c-a0ed-7acb69aec...@d21g2000yqn.googlegroups.com>,
>
>
>
>
>
> *Francesco <xtrigger...@gmail.com> wrote:
> > Hi to all,
>
> > would any of you gentlemen please comment on the reinterpret_casts in
> > the code below?
> > Do you think they're ok or not? Any reference to the standard would be
> > greatly appreciated.
>
> > Thank in advance,
> > FB
>
> > //CODE
> > #include <iostream>
> > #include <iomanip>
>
> > typedef float ( * tMtx )[ 4 ];
>
> > void Fill( tMtx inMtx )
> > {
> > * * for( int c = 0; c < 16; ++c )
> > * * * * inMtx[ c / 4 ][ c % 4 ] = c;
> > }
>
> > void Print( tMtx inMtx )
> > {
> > * * std::cout << "n->" << inMtx << std::endl;
> > * * for( int c1 = 0; c1 < 4; ++c1 )
> > * * {
> > * * * * for( int c2 = 0; c2 < 4; ++c2 )
> > * * * * * * std::cout << std::setw( 5 ) << inMtx[ c1 ][ c2 ];
> > * * * * std::cout << std::endl;
> > * * }
> > * * std::cout << std::endl;
> > }
>
> > int main()
> > {
> > * * float mtx1[ 16 ] = { 0 };
> > * * float mtx2[ 4 ][ 4 ];
> > * * float * mtx3 = new float[ 16 ];
> > * * float * mtx4 = reinterpret_cast< float * >( new float[ 4 ][ 4 ] );
>
> > * * // are these casts OK?
> > * * Fill( reinterpret_cast< tMtx >( mtx1 ) );
> > * * Fill( mtx2 );
> > * * Fill( reinterpret_cast< tMtx >( mtx3 ) );
> > * * Fill( reinterpret_cast< tMtx >( mtx4 ) );
>
> > * * Print( reinterpret_cast< tMtx >( mtx1 ) );
> > * * Print( mtx2 );
> > * * Print( reinterpret_cast< tMtx >( mtx3 ) );
> > * * Print( reinterpret_cast< tMtx >( mtx4 ) );
>
> > * * delete[] mtx3;
> > * * delete[] mtx4;
>
> > * * std::cin.get();
> > }
> > //ENDCODE
>
> It's doable, but I would do it differently:
>
> // begin code
> typedef float m16[16];
> typedef float m44[4][4];
>
> void Fill(m44& v) {
> * *for(int c = 0; c < 16; ++c)
> * * * v[c / 4][c % 4] = c;
>
> } *
>
> void Fill(m16& v) {
> * *Fill(reinterpret_cast<m44&>(v));
>
> }
>
> void Print(const m44& v) {
> * *cout << "n->" << v << endl;
> * *for (int c1 = 0; c1 < 4; ++c1) {
> * * * for (int c2 = 0; c2 < 4; ++c2)
> * * * * *cout << setw(5) << v[c1][c2];
> * * * cout << endl;
> * *}
> * *cout << endl;
>
> }
>
> void Print(const m16& v) {
> * *Print(reinterpret_cast<const m44&>(v));
>
> }
>
> int main()
> {
> * *float mtx1[16] = { 0 };
> * *float mtx2[4][4];
>
> * *Fill(mtx1);
> * *Fill(mtx2);
>
> * *Print(mtx1);
> * *Print(mtx2);
>
> * *cin.get();}
>
> // end code
>
> Even if you are stuck with the Fill and Print you have, I would still
> wrap the casts in functions that take the appropriate types. That way
> you don't have (1) reinterpret_cast all over your code and (2) it is
> less likely that someone will reinterpret_cast the wrong sort of
> variable.- Nascondi testo citato
>
> - Mostra testo citato -
Thanks for the answers and hints.
I was just interested in knowing if casting from a "flat" pointer to a
multidimensional array (or backwards) is formally defined, undefined
behavior or implementation defined.
For the record: I've found an old thread in comp.lang.c where people
had mixed feelings about the issue and it seems that both standards (C
and C++) are not that clear on the subject.
http://groups.google.it/group/comp.l...141614adee786/
Summary: the memory layout of something like float [16] should be the
same as float[4][4] but since the implementation might "magically" do
different bounds checking (??), the following code might cause trouble
on some (??) implementations:
//CODE
#include <cassert>
int main()
{
float array44[4][4];
// DEFINED, UB OR IMPLEM DEFINED ?
float * ptr = reinterpret_cast<float*>( array44 );
ptr[6] = 123.123;
assert( (void*)&array44[1][2] == (void*)&ptr[1*4+2] );
// OPPOSITE CASE
float array16[16] = {0};
// DEFINED, UB OR IMPLEM DEFINED ?
float (*ptr44)[4] = reinterpret_cast<float(*)[4]>( array16 );
ptr44[1][2] = 123.123;
assert( (void*)&array16[1*4+2] == (void*)&ptr44[1][2] );
}
//ENDCODE
Again for the record: I'm interested in using the flat to
multidimensional cast because I'd prefer to use the [][][] in some
functions that have as input flat arrays (created by somebody else)...
Thanks a lot again,
Francesco