Объект есть область памяти; lvalue (адрес) есть выражение,
ссылающееся на объект. Очевидный пример адресного выражения - имя
объекта. Есть операции, дающие адресные выражения: например, если Е
- выражение типа указатель, то *Е - адресное выражение, ссылающееся
на объект, на который указывает Е. Термин "lvalue" происходит из
выражения присваивания Е1=Е2, в котором левый операнд Е1 должен
быть адресным (value) выражением. Ниже при обсуждении каждого
оператора указывается, требует ли он адресные операнды и
возвращает ли он адресное значение.
6. Преобразования
Определенные операции могут в зависимости от их операндов
вызывать преобразование значения операнда от одного типа к другому.
В этой части объясняется, каков ожидаемый результат таких
преобразований. В #6.6 содержится краткое описание преобразований,
требуемых наиболее стандартными операциями; оно будет дополняться
по мере надобности в процессе обсуждения каждой операции. В #8.5.6
описываются преобразования, определяемые пользователем.
6.1 Символы и целые
Символ или короткое целое могут использоваться, если может
использоваться целое. Во всех случаях значение преобразуется к
целому. Преобразование короткого целого к длинному всегда включает
в себя знаковое расширение; целые являются величинами со знаком.
Содержат символы знаковый разряд или нет, является машинно-зависимым; см. #2.6. Более явный тип unsigned char ограничивает
изменение значения от 0 до машинно-зависимого максимума.
В машинах, где символы рассматриваются как имеющие знак
(знаковые), символы множества кода ASCII являются положительными.
Однако, символьная константа, заданная восьмеричной esc-
последовательностью подвергается знаковому расширению и может стать
отрицательным числом; так например, '\377' имеет значение -1.
Когда длинное целое преобразуется в короткое или в char, оно
урезается влево; избыточные биты просто теряются.
6.2 Float и doublе
Для выражений float могут выполняться действия арифметики с
плавающей точкой одинарной точности. Преобразования между числами
одинарной и двойной точности выполняются настолько математически
корректно, насколько позволяет аппаратура.
6.3 Плавающие и целые
Преобразования плавающих значений в интегральный тип имеет
склонность быть машинно-зависимым. В частности, направление
усечения отрицательных чисел различается от машины к машине. Если
предоставляемого пространства для значения не хватает, то результат
не определен.
Преобразование интегрального значения в плавающий тип выполняются
хорошо. При нехватке в аппаратной реализации требуемых бит
возникает некоторая потеря точности.
6.4 Указатели и целые
Выражение целого типа можно прибавить к указателю или вычесть из
него; в таком случае первый преобразуется, как указывается при
обсуждении операции сложения.
Можно производить вычитание над двумя указателями на объекты
одного типа; в этом случае результат преобразуется к типу int или
long в зависимости от машины; см. #7.4.
6.5 Unsigned
Всегда при сочетании целого без знака и обычного целого обычное
целое преобразуется к типу unsigned и результат имеет тип
unsigned. Значением является наименьшее целое без знака, равное
целому со знаком (mod 2**(размер слова)) (т.е. по модулю 2**(размер
слова)). В дополнительном двоичном представлении это преобразование
является пустым, и никаких реальных изменений в двоичном
представлении не происходит.
При преобразовании целого без знака в длинное значение результата
численно совпадает со значением целого без знака. Таким образом,
преобразование сводится к дополнению нулями слева.
6.6 Арифметические преобразования
Большое количество операций вызывают преобразования и дают тип
результата одинаковым образом. Этот стереотип будет называться
"обычным арифметическим преобразованием".
Во-первых, любые операнды типа char, unsigned char или short
преобразуются к типу int.
Далее, если один из операндов имеет тип double, то другой
преобразуется к типу double и тот же тип имеет результат.
Иначе, если один из операндов имеет тип unsigned long, то другой
преобразуется к типу unsigned long и таков же тип результата.
Иначе, если один из операндов имеет тип long, то другой
преобразуется к типу long и таков же тип результата.
Иначе, если один из операндов имеет тип unsigned, то другой
преобразуется к типу unsigned и таков же тип результата.
Иначе оба операнда должны иметь тип int и таков же тип
результата.
6.7 Преобразования указателей
Везде, где указатели присваиваются, инициализируются,
сравниваются и т.д. могут выполняться следующие преобразования.
Константа 0 может преобразовываться в указатель, и гарантируется,
что это значение породит указатель, отличный от указателя на
любой объект.
Указатель любого типа может преобразовываться в void*.
Указатель на класс может преобразовываться в указатель на
открытый базовый класс этого класса; см. #8.5.3.
Имя вектора может преобразовываться в указатель на его первый
элемент.
Идентификатор, описанный как "функция, возвращающая ...", всегда,
когда он не используется в позиции имени функции в вызове,
преобразуется в "указатель на функцию, возвращающую ...".
6.8 Преобразования ссылок
Везде, где инициализируются ссылки, может выполняться следующее преобразование.
Ссылка на класс может преобразовываться в ссылку на открытый
базовый класс этого класса; см. #8.6.3.
|