Лекции.Орг


Поиск:




Категории:

Астрономия
Биология
География
Другие языки
Интернет
Информатика
История
Культура
Литература
Логика
Математика
Медицина
Механика
Охрана труда
Педагогика
Политика
Право
Психология
Религия
Риторика
Социология
Спорт
Строительство
Технология
Транспорт
Физика
Философия
Финансы
Химия
Экология
Экономика
Электроника

 

 

 

 


Левосторонние значения (lvalue)




Чтобы получить представление о понятиях lvalue и rvalue, проще всего рассмотреть, как выглядит некая переменная с точки зрения компилятора, так сказать "изнутри".int i = 10;

С переменной i связаны две вещи: адрес и значение объекта, который она обозначает. Пусть, для определенности, адрес i — 0x1000. Значение, помещенное по этому адресу, как мы видим, — число 10. Незаметно для нас компилятор попеременно использует то одно, то другое из этих двух чисел. Например:int j; j = i;

В этом месте компилятор должен сгенерировать команду (или последовательность команд), которая означает следующее: «извлечь значение переменной i (число 10, записанное по адресу 0x1000) и записать его по адресу переменной j».

Или:++i; «Нарастить то, что находится по адресу переменной i (0x1000) на 1»

.i = 20; «Поместить по адресу 0x1000 значение 20».

В отличие от переменной i, с литералом 20 никакие адреса не связаны, только значение. В частности, выражения вида: ++20; 20 = 10; никакого смысла в С или C++ не имеют. Таким образом, с любым выражением связаны либо адрес и значение, либо только значение.

 

Для того, чтобы отличать выражения, обозначающие объекты, от выражений, обозначающих только значения, ввели понятия lvalue и rvalue. Изначально слово lvalue использовалось для обозначения выражений, которые могли стоять слева от знака присваивания (left-value); им противопоставлялись выражения, которые могли находиться только справа от знака присваивания (right-value). Развитие языков C и C++ привело к утрате словом lvalue своего первоначального значения. Иногда lvalue трактуют также как locator value.

 

С каждой функцией компилятор также связывает две вещи: ее адрес и ее тело («значение»). При необходимости выражение, обозначающее функцию, компилятор может привести к указателю на эту функцию. «Значениями» функций в языках C и C++ оперировать нельзя. В спецификации языка C++ термин lvalue относится также и к выражениям, обознающим функции. В стандарте языка C для выражений, обозначающих функции, используется отдельный термин — function designator.

Необходимо подчеркнуть, что lvalue/rvalue является свойством не объектов и/или функций, а выражений. Например:char a [10];

i, ++i, *&i, a[i] — lvalue, однако:10,i+1,i++ — rvalue; modifiable lvalues, non-modifiable lvalues.

Не все выражения, являющиеся lvalue, могут быть использованы для модификации обозначаемых ими объектов. Например, если t определена как "const int& t = i;", выражение t, будучи lvalue, не может быть использовано для модификации объекта, который оно обозначает. Такие выражения называют non-modifiable lvalues; им противопоставляют modifiable lvalues, которые могут быть использованы для модификации обозначаемых ими объектов.

lvalue-to-rvalue conversion

Очевидно, что если мы будем использовать любое из приведенных ранее lvalue-выражений в контексте, требующем значения объекта (например, в правой части операции присваивания), использование компилятором адресов будет ошибкой. Т.е., хотя выражение i является lvalue ("адрес и значение"), компилятор должен использовать соответствующее rvalue ("значение"). В терминах стандарта C++ это называется преобразованием lvalue к rvalue (lvalue-to-rvalue conversion).

Критерии lvalue/rvalue

В качестве критерия того, является ли некоторое выражение e lvalue, часто предлагают использовать возможность помещения этого выражения по левую сторону от знака присваивания, т.е. если выражение "e =..." допустимо, то e — lvalue. Однако этот критерий «не работает». Во-первых он не «пропускает» некоторые lvalues. Например, хотя выражения, состоящие только из имени массива или функции, являются lvalue, они не могут стоять по левую сторону от '='. Во-вторых он может ложно «диагностировать» некоторые rvalues как lvalues. Например, в C++ для rvalues классов можно вызывать функции члены, поэтому некоторые rvalues вполне могут находиться слева от '=':class C { };

int main()

{

C() = C(); // OK

return 0;

}

Данная программа, хотя и не слишком осмысленна, вполне «законна» с точки зрения спецификации языка C++. При этом выражение С(), стоящее слева от '=', по правилам языка C++ является rvalue,

rvalue:

Выражения, обозначающие временные объекты. В частности, результат вызова функций, возвращающих объекты не по ссылке; результат встроенных операций +, -. *, / и т.п.; явное создание временной переменной int() или C(); преобразования не к ссылочным типам и т.д.

Результат встроенной операции взятия адреса (&) — rvalue типа указатель.

Результат встроенных постфиксных операций ++, --.

Литералы за исключением строковых.

Константы перечислений.

lvalue:

Выражения, непосредственно обозначающие объект, non-modifiable в случае const-квалификации. Например, имя переменной, параметра функции и т.п.

Выражения ссылочных типов. non-modifiable в случае const-квалификации. В частности, результат вызова функций, возвращающих объекты по ссылке; выражения, состоящие из имен ссылочных переменных; операции преобразования к ссылочному типу и т.д.

Результат встроенной операции разыменования (*) — lvalue указуемого типа; non-modifiable в случае const-квалификации.

Результат встроенных префиксных операций ++, --.

Имя функции — non-modifiable lvalue; может быть преобразовано к rvalue «указатель на функцию».

Имя массива — non-modifiable lvalue; может быть преобразовано к rvalue «указатель на первый элемент массива».

Строковые литералы — non-modifiable lvalue; может быть преобразовано к rvalue «указатель на char/wchar_t».

 





Поделиться с друзьями:


Дата добавления: 2015-10-01; Мы поможем в написании ваших работ!; просмотров: 553 | Нарушение авторских прав


Поиск на сайте:

Лучшие изречения:

Наука — это организованные знания, мудрость — это организованная жизнь. © Иммануил Кант
==> читать все изречения...

2243 - | 2054 -


© 2015-2024 lektsii.org - Контакты - Последнее добавление

Ген: 0.01 с.