2015-12-11 2 views
5

Попытка узнать lvalues, rvalues и выделение памяти для них. Таким образом, с большим количеством учебных материалов есть немного хаоса.Как rvalues ​​в C++ хранится в памяти?

rvalue - это значение, которое должно существовать только в пределах выражения, в котором оно было создано (до C++ 11, по крайней мере). Таким образом, он имеет адрес и блок памяти, которые он занимает. Но по определению мы не можем получить адрес rvalue, потому что это временный объект, в отличие от lvalue. Но даже до C++ 11 нам удалось получить адрес rvalue, вернув его из функции и сохранив в тип ссылки const (ну, я думаю, это не адрес, а значение).

Точнее, как работает rvalue? Как долго программа или ОС действительно помнят место памяти, где rvalue был создан и помечен как выделенный, а другой объект не может занять его место?

Как я вижу, сейчас rvalues хранятся точно так же, как lvalues, но мы просто имеем другие права доступа к ним. И у них есть другие типы освобождения - для lvalues, выходящих из области видимости, для rvalues может быть оптимизировано путем существования в пределах выражения или до тех пор, пока на нем больше нет ссылок.

+4

lvalues ​​и rvalues ​​являются категориями выражений. Они не используют никакого хранилища. Использование хранилища - это * объекты *. (а иногда и ссылки). Кажется, вы пишете «rvalue», когда на самом деле вы имеете в виду «временный объект». –

+0

Я не думаю, что rvalues ​​должен иметь адрес вообще. Их можно просто оценить в реестрах. –

+0

@ M.M, вы правы. –

ответ

5

Короткий ответ: это зависит от реализации.

Главной причиной этого является, как всегда, свобода компилятора для улучшения характеристик вашего кода. Более конкретный способ понять это состоит в том, чтобы помнить, что значение может быть сохранено в регистре вашего ЦП и никогда не находиться в вашей памяти, что более или менее означает, что значение не имеет адреса. Я не буду делать ставки на все, что у меня есть, но это, вероятно, одна из основных причин, почему «мы не можем получить адрес rvalue».

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

4

Концептуально, rvalues ​​живут на «стек». Если вы доберетесь до их адреса, это концептуально адрес где-то в стеке. Если адрес не принимается вообще, объект никогда не может существовать до тех пор, пока компилятор устанавливает правильные инструкции, чтобы он отображался , как будто он был создан.

Даже если сущность действительно создана там, где именно она находится, зависит от разных вещей, и она может даже не оказаться в стеке вообще: она может находиться в текущем фрейме стека, но может также быть другим фреймом стека или в какой-то причине, если rvalue заканчивается тем, что копируется/перемещается туда, а компилятор выполняет копирование. Если значение rvalue привязано к const&, оно может также находиться где-то в другом месте, если оно не было.

Срок службы rvalue связан правилами языка. Как это фактически реализовано, в значительной степени зависит от компилятора и/или от ABI, которым он придерживается.

Смежные вопросы