LINUX.ORG.RU

Статически создаваемые объекты

 ,


0

2

Собственно, пример:

https://godbolt.org/z/YEPoddsss

Здесь речь идёт от std::initializer_list и о std::tuple.

Функции f и g принимают константную ссылку (на уровене ассемблера то же самое, что и указатель). Сами передаваемые объекты не предполагают динамического выделения памяти. То есть по факту они представляют одинаковый набор байт каждый вызов функции. Значит, с точки зрения самого алгоритма ничто не мешает создать объект в секции констант и передавать просто ссылку на него (ведь ссылка константная, а значит f и g не могут менять объект). Однако нет, каждый вызов f и g объекты конструируются на стеке. Хотя у tuple вообще есть constexpr конструктор.

Почему так? И способен ли современный C++ при каких-то условиях сконструировать временный объект во время компиляции и передавать ссылку на него в секции констант вместо конструирования на стеке? Если нет, то есть ли какие-то причины, почему эту фичу не реализуют?

UPD: Для std::tuple это работает как надо, если объявить аргумент отдельно как static переменную -https://godbolt.org/z/Y9q6Yh3q3. Для std::initializer_list не работает даже в этом случае (просто теперь он инициализируется не на стеке). Возможно ли создать аналог initializer_list (возможность передать в функцию переменное число аргументов с нормальной типобезопасностью и преобразованием типов при необходимости к правильному, а не как у темплейтов), который бы умел в статическое создание?

★★★★★

Последнее исправление: KivApple (всего исправлений: 3)

C++ при каких-то условиях сконструировать временный объект во время компиляции и передавать ссылку на него в секции констант вместо конструирования на стеке? Если нет, то есть ли какие-то причины, почему эту фичу не реализуют?

Нет конечно.

Временный объект должен уничтожиться после того как был использован, то есть должен быть вызван деструктор.

А константы должны жить до конца жизни программы.

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Временный объект должен уничтожиться после того как был использован, то есть должен быть вызван деструктор.

В C++ вполне есть понятие тривиального (или constexpr + все аргументы конструктора constexpr) конструктора и деструктора. Такой по идее создавай 1 раз или 100, разницы не будет наблюдаемой для кода. Но как я понимаю, в стандарте может быть явно прописано, что такая оптимизация не разрешена.

KivApple ★★★★★
() автор топика
Последнее исправление: KivApple (всего исправлений: 2)