6.2 Float и Double
Для выражений 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.
7. Выражения
Приоритет операций в выраженях такой же, как и порядок главных подразделов в этом разделе, наибольший приоритет у первого. Так например, выражения, о которых говорится как об операндах операции + (#7.4) – это те выражения, которые опрделены в ##7.1-7.4. Внутри каждого подраздела операции имеют одинаковый приоритет. В каждом подразделе для рассматриваемых в нем операций определяется их левая или правая ассоциатиность (порядок обработки операндов). Приоритет и ассоциатиность всех операций собран вместе в описании грамматики в #14.
В остальных случаях порядок вычисления выражения неопрделен. Точнее, компилятор волен вычислять подвыражения в том
порядке, который он считает более эффективным, даже если повыражения вызывают побочные эффекты. Порядок возникновения побочных эффектов неопределен. Выражения, включающие в себя коммутативные и асссоциативные операции (*, +, amp;, !, ^), мгут быть реорганизованы произвольным образом, даже при налчии скобок; для задания определенного порядка вычисления вражения необходимо использовать явную временную переменную.
Обработка переполнения и контроль деления при вычислении выражения машинно зависимы. В большинстве существующих реалзаций С++ переполнение целого игнорируется; обработка деления на 0 и всех исключительных ситуаций с числами с плавающей точкой различаются от машины к машине и обычно могут регулроваться библиотечными функциями.
Кроме стандартного значения, описанного в #7.2-7.15, операции могут быть перегружены*, то есть, могут быть заданы их значения для случая их применения к типам, определяемым пользователем, см. #7.16.
– * Этот термин применяется для описания использования в языке одной и той же лексемы для обозначения различных процдур; вид процедуры выбирается компилятором на основании дполнительной информации в виде числа и типа аргументов и т.п. (прим.перев.)
7.1 Основные выражения
Основные выражения, включающие в себя . , -» , индексрование и вызовы функций, группируются слева направо.
список_выражений: выражение список_выражений , выражение
id: идентификатор имя_функции_операции typedef-имя :: идентификатор typedef-имя :: имя_функции_операции
первичное_выражение: id :: идентификатор константа строка this ( выражение ) первичное_выражение [ выражение ] первичное_выражение ( список_выражений opt ) первичное_выражение . id первичное_выражение -» id
Идентификатор есть первичное выражение, причем соответтвенно описанное (#8). Имя_функции_операции есть идентификтор со специальным значением, см. #7.16 и #8.5.1.
Операция ::, за которой следует идентификатор из файловой области видимости, есть то же, что и идентификатор. Это позволяет ссылаться на объект даже в том случае, когда его идентификатор скрыт (#4.1).
Typedef-имя (#8.8) , за которым следует ::, после чего следует идентификатор, является первичным выражением. Typedef -имя должно обозначать класс (#8.5), и идентификатор должен обозначать член этого класса. Его тип специфицируется описанием идентификатора. Typedef-имя может быть скрыто именем, которое не является именем типа. В этом случае typedef-имя все равно может быть найдено и его можно использовать.
Константа является первичным выражением. Ее тип должен быть int, long или double в зависимости от ее формы.
Строка является первичным выражением. Ее тип – «массив символов». Обычно он сразу же преобразуется в указатель на ее первый символ (#6.7).