Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > casting pointers/arrays to multidimensional arrays

Reply
Thread Tools

casting pointers/arrays to multidimensional arrays

 
 
Francesco
Guest
Posts: n/a
 
      11-03-2009
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
 
Reply With Quote
 
 
 
 
James Kanze
Guest
Posts: n/a
 
      11-03-2009
On Nov 3, 3:41 pm, Francesco <xtrigger...@gmail.com> wrote:

> 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.


> //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


They're reinterpret_cast. Formally, I think using the results
of them here is undefined behavior. If you're implementation
says it's OK, they should work. And in practice, most
implementations don't say anything, but they work anyway.

Of course, they're not something you'd want to see in production
code.

--
James Kanze
 
Reply With Quote
 
 
 
 
Francesco
Guest
Posts: n/a
 
      11-06-2009
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
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Multidimensional arrays and arrays of arrays Philipp Java 21 01-20-2009 08:33 AM
Multidimensional arrays in Struts form? geclinke Java 1 06-18-2004 03:31 PM
Multidimensional arrays? anything else? d[ - - ]b ASP .Net 2 05-18-2004 12:17 PM
Cast to multidimensional arrays Jay Java 1 01-30-2004 04:27 PM
Re: deleting multidimensional arrays Rene Eng C++ 0 07-27-2003 08:48 PM



Advertisments