Сделай Сам Свою Работу на 5

R.4 Стандартные преобразования





 

Некоторые операции в зависимости от своих операндов могут вызвать преобразование значения операнда от одного типа к другому. Здесь описываются преобразования, вызванные самыми обычными операциями, и объясняется каковы могут быть результаты таких преобразований. По мере надобности будут даны дополнительные объяснения при обсуждении каждой операции. Подобные преобразования также происходят при инициализации (§R.8.4, §R.8.4.3, §R.12.8, §R.12.1). В §R.12.3 и §R.13.2 описываются преобразования, заданные пользователем, и их соотношения со стандартными преобразованиями. В результате преобразования может получиться адрес, только если результат есть ссылка (§R.8.2.2).

 

R.4.1 Стандартные преобразования для целочисленных

 

Всюду, где требуется целое, можно использовать char, short int, элемент перечисления (§R.7.2) или битовое поле (§R.9.6), причем в знаковом и беззнаковом вариантах. Если int может представлять все значения исходного типа, значение преобразуется к int, иначе оно преобразуется к unsigned int. Это называется стандартным преобразованием для целочисленных.

 

R.4.2 Преобразования целочисленных



 

Если целое преобразуется в беззнаковый тип, то полученное значение есть наименьшее беззнаковое целое, совпадающее с целым со знаком по (mod 2n), где n есть число битов в представлении беззнакового целого. Для представления в дополнительном коде это преобразование лишь концептуальное, никаких изменений в двоичном представлении в действительности не происходит.

Если целое преобразуется к знаковому типу, значение не меняется, при условии, что его можно представить с помощью нового типа, иначе значение определяется реализацией.

 

R.4.3 Значения с плавающей точкой и двойной точностью

 

Для выражений типа float может использоваться арифметика с обычной точностью. Если значение с плавающей точкой меньшей точности преобразуется в значение типа float равной или большей точности, то изменения значения не происходит. Если значение с плавающей точкой большей точности преобразуется в значение типа float меньшей точности и значение находится в пределах, задаваемых представлением типа, то в результате может получиться или ближайшее большее или ближайшее меньшее представимое значение. Если результат оказался вне границ представления типа, поведение неопределено.



 

R.4.4 Целочисленные и числа с плавающей точкой

 

Преобразование значения с плавающей точкой к целочисленному типу сводится к "усечению", т.е. отбрасыванию дробной части. Такие преобразования зависят от машины, в частности в какую сторону будет проходить усечение для отрицательных чисел определяется на разных машинах по разному. Результат считается неопределенным, если значение нельзя представить в целочисленном типе.

Преобразования целочисленных значений к значениям с плавающей точкой математически корректны настолько, насколько это позволяет система команд. Может произойти потеря точности, если целочисленное значение нельзя точно представить как значение с плавающей точкой.

 

R.4.5 Арифметические преобразования

 

Для большинства операций преобразования операндов и тип результата определяются одними и и теми же правилами. Это правило можно назвать "обычными арифметическими преобразованиями".

Если один из операндов есть long double, другой операнд преобразуется в long double.

Иначе, если один из операндов есть double, другой операнд преобразуется в double.

Иначе, если один из операндов есть float, другой операнд преобразуется в float.

Иначе, если стандартные целочисленные преобразования (§R.4.1) происходят над обоими операндами.

Тогда, если один из операндов есть unsigned long, другой операнд преобразуется в unsigned long.

Иначе, если один из операндов есть long int, а другой - unsigned int, то при условии, что long int может представлять все возможные значения unsigned int, значение unsigned int преобразуется в long int, в противном случае оба операнда преобразуются в unsigned long int.



Иначе, если один из операндов есть long, другой операнд преобразуется в long.

Иначе, если один из операндов есть unsigned, другой операнд преобразуется в unsigned.

Иначе, оба операнда должны быть int.

 

R.4.6 Преобразования указателей

 

Всюду, где указатели (§R.8.2.1) присваиваются, инициализируются, сравниваются или используются иным образом, могут происходить следующие преобразования:

Константное выражение (§R.5.19), которое сводится к нулю, преобразуется в указатель, обычно называемый пустым указателем.

Гарантируется, что значение такого указателя будет отлично от любого указателя на объект или функцию.

Указатель на объект любого типа, не являющегося const или volatile, можно преобразовать в void*.

Указатель на функцию можно преобразовать в void*, при условии, что для void* отводится достаточно памяти, чтобы хранить этот указатель.

Указатель на данный класс можно преобразовать в указатель на доступный базовый класс данного класса (§R.10), если такое преобразование не содержит двусмысленность (§R.10.1). Базовый класс считается доступным, если доступны его общие члены (§R.11.1).

Результатом преобразования будет указатель на объект типа базового класса, вложенный в объект типа производного класса. Пустой указатель (0) преобразуется сам в себя.

Выражение типа "массив T" может преобразовываться в указатель на начальный элемент массива.

Выражение типа "функция, возвращающая T" преобразуется в "указатель на функцию, возвращающую T", за исключением тех случаев, когда оно используется как операнд адресной операции & или операции вызова функции ().

 

R.4.7 Преобразования ссылок

 

Всюду, где ссылки (§R.8.2.2) инициализируются (включая передачу параметров (§R.5.2.2) и возврат значения функции (§R.6.6.3)) или используются иным образом, возможны следующие преобразования:

Ссылка на данный класс может быть преобразована в ссылку на доступный базовый класс (§R.10, §R.11.1) данного класса (§R.8.4.3), при условии, что такое преобразование не содержит двусмысленности (§R.10.1.1). Результатом преобразования будет ссылка на объект базового класса, вложенный в объект производного класса.

 

R.4.8 Указатели на члены

 

Всюду, где указатели на члены (§R.8.2.3) инициализируются, присваиваются, сравниваются или используются иным образом, могут происходить следующие преобразования:

Константное выражение (§R.5.19), которое сводится к нулю, преобразуется в указатель на член. Гарантируется, что его значение будет отлично от любых других указателей на члены.

Указатель на член данного класса можно преобразовать в указатель на член производного от данного класса, при условии, что допустимо обратное преобразование от указателя на член производного класса в указатель член базового класса, и что оно выполнимо однозначным образом (§R.10.1.1).

Правило преобразования указателей на члены (т.е. от указателя на член базового класса к указателю на член производного класса) выглядит перевернутым, если сравнивать его с правилом для указателей на объекты (т.е. от указателя на производный объект к указателю на базовый объект) (§R.4.6, §R.10). Это необходимо для гарантии надежности типов.

Отметим, что указатель на член не является указателем на объект или указателем на функцию и правила преобразований таких указателей не применимы для указателей на члены. В частности указатель на член нельзя преобразовать в void*.

 

 

R.5 Выражения

 

Здесь определяются синтаксис, порядок вычисления и назначение выражений. Выражение - это последовательность операций и операндов, которая задает вычисление. Вычисление может выдавать в качестве результата значение и может вызывать побочные эффекты.

Операции могут быть перегружены, т.е. им может быть приписано значение, когда они применяются к выражениям типа класс (§R.9). Применение перегруженных операций преобразуется в вызовы функций в соответствии с описанием в §R.13.4. Перегруженные операции подчиняются синтаксическим правилам, определенным в этом разделе, но требования к типу операнда, адресу и порядку вычисления заменяются на правила вызова функции. Соотношения между операциями, типа ++a означает a+=1, не гарантируются для перегруженных операций (§R.13.4).

В этом разделе описано применение операций к типам, для которых они не являются перегруженными. Перегрузка операций не может изменить правила применения операций к типам, для которых такое применение предусмотрено в самом языке.

Порядок вычисления подвыражений определяется приоритетом и порядком применения операций. Обычные математические правила ассоциативности и коммутативности операций действуют только, если операции действительно ассоциативны или коммутативны. За исключением оговоренных случаев порядок вычисления операндов конкретной операции неопределен. В частности, если в выражении значение изменяется дважды, результат выражения неопределен, если только порядок выполнения не обеспечивается самими операциями, например:

i = v[i++]; // the value of `i' is undefined

i=7, i++, i++; // `i' becomes 9

Реакция на переполнение и деление на нуль при вычислении выражения зависит от реализации. В большинстве существующих реализаций C++ игнорируется переполнение целых. Реакция на деление на нуль и ошибки операций над числами с плавающей точкой варьируется от машины к машине и обычно связана с соответствующими библиотечными функциями.

Кроме оговоренных случаев, операнды типа const T, volatile T, T&, const T& и volatile T& можно использовать, как если бы они имели тип просто T. Аналогично, операнды типа T* const, T*volatile можно использовать, как если бы они имели тип просто T*, за исключением оговоренных случаев. Аналогично, просто тип T можно использовать всюду, где требуется тип volatile T или const T. Эти правила может применять в комбинации, так что const T* volatile можно использовать там, где требуется T*, за исключением оговоренных случаев. При рассмотрении разрешения перегрузки (§R.13.2) такое использование операций не считается стандартным преобразованием операндов.

Если выражение имеет тип "ссылка на T" (§R.8.2.2, §R.8.4.3), значение выражение есть объект типа "T", на который настроена ссылка. Выражение является адресом. Ссылку можно представлять как имя объекта.

Допустимы определенные пользователем преобразования объектов класса в (и обратно) основные типы, указатели и т.д. (§R.12.3) Если они недвусмысленны (§R.13.2), такие преобразования могут применяться транслятором всегда, когда появляется объект типа класса в качестве операнда операции, в качестве инициализирующего выражения (§R.8.4), в качестве выражения, задающего условие (§R.6.4), или в качестве выражения, используемого в операторе цикла (§R.6.5), или в качестве значения, возвращаемого функцией (§R.6.6.3), или в качестве параметра функции (§R.5.2.2).

 

 








Не нашли, что искали? Воспользуйтесь поиском по сайту:



©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.