Почему не работает каст int(&)[Rs][Cs] к int**?
Экспериментировал, пытался сделать небольшой хак:
void int_array_2d_show_impl(int** array, std::size_t rows, std::size_t cols)
{
for (std::size_t row = 0; row < rows; ++row)
for(std::size_t col = 0; col < cols; ++col)
std::clog << array[row][col]
<< (col == cols-1 ? '\n' : ' ');
}
template<std::size_t Rows, std::size_t Cols>
void int_array_2d_show_ref(int (&array)[Rows][Cols])
{
int_array_2d_show_impl((int**)array,Rows,Cols);
}
Но это не работает. Статический анализатор пишет, что static_cast не позволяет кастить int(*)[N] к int**. Сишный каст, естественно, работает, но ломает код, и int_array_2d_show_impl ничего не выводит. Почему так происходит? В чем тут UB? Они по разному в памяти хранятся чтоли? Такой код не выводит ничего, но выполняется без compile time и без run time ошибок. Хотя бы мусора же должен был вывести...
Post Scriptum: Получилось так:
void int_array_2d_show_impl(int* array, std::size_t rows, std::size_t cols)
{
for (std::size_t row = 0; row < rows; ++row)
for(std::size_t col = 0; col < cols; ++col)
std::clog << array[row*cols+col]
<< (col == cols-1 ? '\n' : ' ');
}
template<std::size_t Rows, std::size_t Cols>
void int_array_2d_show_ref(int (&array)[Rows][Cols])
{
int_array_2d_show_impl(*array,Rows,Cols);
}
Ответы (1 шт):
Потому что int[Rows][Cols] и int** - это принципиально разные типы, по-разному хранящиеся в памяти.
В первом случае - это одна непрерывная область памяти, в которой выражения типа a[3][2] рассчитывает сам компилятор, исходя из того, что тип int[Rows][Cols] - это указатель на int[Cols] (!), а не на int*.
В int** мы имеем массив указателей, каждый их которых указывает на какой-то массив int'ов.
Вот примерный набросок размещения в памяти:
Еще раз - самое главное - в int[Rows][Col] вы имеете дело не с указателями на указатели на int, а с указателями на int[Cols]. А это совершенно разные типы!
