указатель на массив не совместим с указателем на массив const?
Да, они несовместимы, вы не можете изменить вложенный квалификатор const, int (*a)[42]
не совместим с int const (*b)[42]
, связанным , поскольку double **
не совместим с double const **
Верно ли мое предположение, что это не приводит к дыре в правильности констант?
Ну, вы добавляете const квалификатор, так что нет. Фактически, возвращение non const не выдает предупреждение и не нарушает правильность const в соответствии с тем же правилом, которое не позволяет вам добавлять const. Но такой код очень запутан, но не является неопределенным поведением.
shape *fooshapes(const foo *f)
{
return f->shapes;
}
Является ли явное приведение нарушает стандарт здесь?
Строго , Да, как сказал компилятор, типы несовместимы, однако я не думаю, что это приведет к ошибке в любом реальном классическом оборудовании.
Дело в том, что стандарт не гарантирует, что double *a
и double const *b
имеют одинаковый размер или даже одинаковое значение, а просто гарантирует, что a == b
даст положительное значение. Вы можете рекламировать любой double *
до double const *
, но, как я уже сказал, вы должны продвигать его Когда вы разыгрываете, вы ничего не продвигаете, потому что массив / указатель вложен. Так что это неопределенное поведение.
Это «вы просто не можете сделать это в C», вы можете спросить, но «что я должен делать?». Ну, я не вижу цели вашей структуры, ни вашего указателя на массив в структуре. Чтобы решить более глубокую проблему вашей структуры данных, вы должны задать другой вопрос, в котором вы больше говорите о том, что вы делаете с этим кодом. Например, ваша функция может сделать что-то вроде этого:
uint8_t const *fooshapes(const foo *f, size_t i)
{
return f->shapes[i];
}