cpp-ru / ideas

Идеи по улучшению языка C++ для обсуждения
https://cpp-ru.github.io/proposals
Creative Commons Zero v1.0 Universal
91 stars 0 forks source link

Стандиртизовать и улучшить локальные массивы переменной длины #600

Open Panzerschrek opened 1 month ago

Panzerschrek commented 1 month ago

В C99 Существуют массивы переменной длины (variable-length arrays), которые могут быть использованы в качестве локальных переменных. Память под них выделяется динамически со стека.

GCC позволяет также использовать такие массивы в C++. Элементы таких массивов инициализируются конструктором по умолчанию, также вызываются должным образом деструкторы. Инициализация чем-либо, кроме конструктора по умолчанию, не возможна.

Подобного рода массивы полезны для хранения некоторых промежуточных данных переменной длины, когда ожидаемое количество элементов не велико и выделение памяти из кучи слишком накладно.

К сожалению в C++ такие массивы не являются частью стандарта. Если нужно выделить локальный блок памяти переменной длины, приходится или использовать std::vector, или буфер фиксированного размера, с использованием того же std::vector, если размера не хватает.

Поскольку подобные массивы являются весьма полезными, предлагаю сделать их частью стандарта C++.

Но в том виде, в котором они сейчас реализованы в GCC, их использовать не очень хорошо. В текущей реализации есть ряд проблем.

Память на стеке (очевидно) весьма ограничена. Можно её исчерпать, если объявленный массив переменной длины слишком большой. Поэтому предлагаю, дабы минимизировать вероятность переполнения стека, разрешить реализации на своё усмотрение выделять памяти из кучи (оператором new[]). Например, если размер аллокации выше порогового - выделять память из кучи, иначе - на стеке. При этом компилятор должен сам вставлять код, который освободит должным образом память, ранее выделенную из кучи (оператором delete[]). В зависимости от целевой платформы/среды память может всегда выделяться только со стека или только из кучи.

Ещё одна проблема массивов переменной длины в реализации от GCC - негибкость инициализации. Эту негибкость предлагается устранить, добавив больше вариантов инициализации: