Непонятное ограничение по поводу noptr-new-declartor

0
noptr-new-declarator:
    [ expression ] attribute-specifier-seq_opt
    noptr-new-declarator [ constant-expression ] attribute-specifier-seq_opt

Непонятно, почему в последнем случае разрешенного noptr-new-declarator в квадратных скобках используется точно постоянное выражение.

Я не вижу ничего критического, если мы позволяем выделить что-то вроде

int n = 10;
float *fp = new float[5][n];
  • 1
    Я думаю, что для согласованности float[5][n] должен определять тип, а var-массивы еще не поддерживаются стандартом, то есть вы не можете (пока) определить float array[5][n] если n не является const или constexpr (или #defined )
  • 0
    @vsoftco Но float[n][5] разрешено Стандартом в этом случае. Более того, как я понял, это не var-массив. Это просто динамически создаваемый массив.
Показать ещё 6 комментариев
Теги:
arrays
allocation

1 ответ

1
Лучший ответ

Когда вы компилируете:

float* f = new float[2][2];

У вас есть следующая ошибка:

не может преобразовать 'float (*) [2] в' float * при инициализации

В нем объясняется, что new float[2][2] генерирует связку float*[2] а не только указатель на float. Тип переменной, которую вы используете для хранения результата, должен знать свой размер во время компиляции, чтобы разрешить доступ к элементам массива.

Легко видеть, что размер зависит от размера не первого массива, если вы выполняете небольшую арифметику указателя (онлайн-код):

auto f1 = new float[2][10]; 
std::cout << "F1[0]: " << f1[0] << std::endl;
std::cout << "F1[1]: " << f1[1] << std::endl;
std::cout << "F1[1] - F1[0] : " << f1[1] - f1[0] << std::endl;

auto f2 = new float[2][5];  
std::cout << "F2[0]: " << f2[0] << std::endl;
std::cout << "F2[1]: " << f2[1] << std::endl;
std::cout << "F2[1] - F2[0] : " << f2[1] - f2[0] << std::endl;

auto f3 = new float[5][5];  
std::cout << "F3[0]: " << f3[0] << std::endl;
std::cout << "F3[1]: " << f3[1] << std::endl;
std::cout << "F3[1] - F3[0] : " << f3[1] - f3[0] << std::endl;

Этот код выводит:

F1[0]: 0x600010480
F1[1]: 0x6000104a8
F1[1] - F1[0] : 10
F2[0]: 0x600048580
F2[1]: 0x600048594
F2[1] - F2[0] : 5
F3[0]: 0x6000485b0
F3[1]: 0x6000485c4
F3[1] - F3[0] : 5

Все эти размеры должны вычисляться во время компиляции, что делает constexpr обязательным.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню