Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
Panzerschrek opened this issue Sep 28, 2024 · 0 comments

Comments

@Panzerschrek
Copy link

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

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

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

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

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

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

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

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

  • Инициализация значением-заполнителем. В качестве инициализатора предоставляется одно значение внутри {}, оно будет скопировано (конструктором копирования) во все элементы массива.
  • Инициализация парой итераторов [begin; end) внутри {}. Элементы массива инициализируются элементами, доступными через итераторы в этом диапазоне. Расстояние между парой итераторов должно быть равно количеству элементов массива, иначе - неопределённое поведение.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant