Почему у rvalues ​​нет адреса? - PullRequest
6 голосов
/ 10 сентября 2011

Почему у rvalues ​​нет адреса памяти?Разве они не загружаются в ОЗУ при выполнении программы или ссылаются на значения, хранящиеся в регистрах процессора?

Ответы [ 5 ]

10 голосов
/ 10 сентября 2011

Ваш вопрос («Почему у rvalues ​​нет адреса памяти?») Немного запутан. Rvalue является своего рода выражением. Выражения не имеют адресов: объекты имеют адреса. Правильнее было бы спросить: «Почему нельзя применить оператор address-of к выражению rvalue?»

Ответ на этот вопрос довольно прост: вы можете взять только адрес объекта, и не все rvalue-выражения относятся к объектам (например, выражение 42 имеет значение, но не относится к объекту).

Некоторые выражения rvalue ссылаются на объекты, но такие объекты не сохраняются. Объект, на который ссылается выражение rvalue, является временным объектом и уничтожается в конце выражения, в котором он создан. Такие объекты действительно имеют адреса (вы можете легко обнаружить это, вызвав функцию-член для временного объекта; указатель this должен указывать на временный объект, и, следовательно, временный объект должен иметь адрес).

Это принципиальное различие между выражениями lvalue и выражениями rvalue. Выражения Lvalue относятся к объектам, которые имеют постоянство: объект, к которому относится выражение lvalue , сохраняется за пределами одного выражения .

1 голос
/ 10 сентября 2011

Вопрос смешивает два разных аспекта, связанных с «спецификацией» и «реализацией».

«Спецификация» определяет некоторые абстрактные правила, которые определяют, как язык ведет себя по отношению к абстрактной машине, с которой он работает,Адаптируйте эту «абстрактную машину» к «реальной» под ней, это цель компилятора (а не языка).

Что требует спецификация, так это то, что с точки зрения языка - «хранилище»(часть памяти с правильным адресом) дается только объектам, которые имеют имя (для существования области, в которой живет имя) или которые динамически распределяются с явным запросом (new),Все остальное является «временным»: присваивать, копировать и перемещать как объект, но не требуется для существования в четко определенном и стабильном месте.По крайней мере, не для целей языка.

Конечно, это должно где-то оставаться (физически), так что вы можете - с помощью соответствующего приведения или преобразования - пытаться угадать адрес памяти.Но спецификация языка не дает какого-либо согласованного поведения, если вы пытаетесь его активно использовать.Это означает, что разные компиляторы могут вести себя по-разному и оптимизировать, тем лучше они могут соответствовать реальной машине, на которую они нацелены.

1 голос
/ 10 сентября 2011

Представьте rvalue как значение выражения . Само значение не имеет адреса. Но объекты , включенные в выражение, имеют адрес. Вы можете взять адрес объекта , даже если это временный объект.

Учтите это,

const int & i = 10; //ok

Здесь 10 является значением r, поэтому выглядит , что &i является адресом 10 Нет, это неправильно. &i - это адрес временного объекта типа int, который создается из выражения 10. И поскольку временный объект не может быть привязан к неконстантной ссылке, я использую const. Это означает, что следующее является ошибкой:

int & i = 10; //error
0 голосов
/ 10 сентября 2011

Просто возьмите этот случай

int a = 1 + 2;

1 + 2 разрешается до 3.

Задайте себе вопрос:

  • Является ли 3 объектом?
  • Где находится 3 в памяти?

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

Если rvalues ​​будет адресуемым, это означает, что вы можете объявить указатель того места, где ваш компьютер решил хранить 3

int* a = &3;

Это кажется правильным?:)

0 голосов
/ 10 сентября 2011

Что вы имеете в виду, у rvalues ​​есть адрес. Когда-либо пробовал

Type const value& = rvalue;
Type const* address = &value;
...