Re: Validity of pointer conversions
Salt_Peter 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};
OK, it prints:
[john@localhost src]$ ./foobar-cpp
99 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
as expected. When initialising a built-in array with initial values, the
rest members of the array that are not explicitly assigned with an
initial value, are initialised with 0.
// 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));
I am not looking for ways to do it. I am just asking if these specific
uses are guaranteed to work as expected.
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).
Hacking is not programming. Respect your types at all costs. Its
directive #1, no exceptions.
Anytime you fool a compiler you are preventing it to help you code.
Basicly, you'll code as if it is a 10x5 matrix and then one day
something will change thats beyond your control.
You'll come back 6 months from now, look at your code, needing to
modify it (ie: add features) and reach for the Asprin tablets (imagine
the client-user of your code trying to figure it all out). An apple is
an apple, if you threat it like an orange then you'll eventually fall
in a hole called undefined behaviour. You will, its a question of
time.
Clients/Customers don't like hacks, and sometimes - that client/
customer ... is you.
I am asking if it is a *valid* low-level behaviour, and not an undefined
behaviour. We could use
int (*p)[5]= static_cast<int (*)[5]> (static_cast<void *>(&array[0]));
instead of the reinterpret_cast instead.
My question (actually what I think I know and I want others to verify)
is, a built in array of type T, is a sequence of its members of type T,
and thus we can treat it as arrays of various forms.
Consider another example:
#include <iostream>
#include <cstdlib>
int main()
{
using namespace std;
const char *pc= "This is a test.";
// 100% guaranteed to work
const char *p1= pc;
while(*p1)
cout<< *p1++;
cout<< endl;
// 100% guaranteed to work
const char (*p2)[16]= reinterpret_cast<const char (*)[16]>(pc);
for(size_t j= 0; j<sizeof(*p2)/sizeof(**p2); ++j)
cout<< p2[0][j];
cout<< endl;
// ==> Here is my question. Is it 100% guaranteed to work? AFAIK yes.
const char (*p3)[8]= reinterpret_cast<const char (*)[8]>(pc);
for(size_t i= 0; i<2; ++i)
for(size_t j= 0; j<sizeof(*p3)/sizeof(**p3); ++j)
cout<< p3[i][j];
cout<< endl;
}