Qubc
@Qubc
Ненавижу полисемию.

Каковы правила конвертации указателя на массив неопределенной длины в указатель на массив определенной длины?

int main () {
    int ( *p2 ) [ 2 ] = nullptr;
    int ( *p )[] = nullptr;

Почему поведение зависит от версии компилятора?
p = p2;
    // g++ 9.5 и msvc v143 cannot convert 'int (*)[2]' to 'int (*)[]' in assignment 
    // g++ >= 10.1 OK

Почему нельзя в C++ (в C можно)?
p2 = p; 
    //cannot convert 'int (*)[]' to 'int (*)[2]' in assignment
     
}
  • Вопрос задан
  • 263 просмотра
Решения вопроса 2
Adamos
@Adamos
С++ - язык более высокого уровня, тут компилятор не позволит вам выстрелить себе в ногу неявным приведением сена к соломе. Нужно объявить его явно.
static_cast - если компилятор готов согласиться с вами, что одно можно просто привести к другому во время компиляции.
dynamic_cast - если вы приводите указатель на родительский класс к указателю на дочерний
и reinterpret_cast - если вы приводите по-сишному, "ногой в дверь", уверены в себе и не нуждаетесь в подсказках компилятора насчет того, что делаете.
Ответ написан
@code_panik
В выражении p = p2 мы выполняем неявное преобразование встроенных типов, для которых в стандарте не описаны правила преобразования. То есть такое преобразование не гарантировано, но может быть реализовано компилятором, например
#include <type_traits>
using namespace std;

int main() {
    static_assert(std::is_convertible<int(*)[2], int(*)[]>::value, "Non-convertible");
    return 0;
}

компилируется в gcc 12.2, в clang 15.0 - ошибка.

Существует старое не принятое предложение о закреплении такого преобразования стандартом.
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы