<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://camokathomelab.servebeer.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B8%D0%BF%D0%B0</id>
	<title>Приведение типа - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://camokathomelab.servebeer.com/mediawiki/index.php?action=history&amp;feed=atom&amp;title=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B8%D0%BF%D0%B0"/>
	<link rel="alternate" type="text/html" href="https://camokathomelab.servebeer.com/mediawiki/index.php?title=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B8%D0%BF%D0%B0&amp;action=history"/>
	<updated>2026-07-18T01:34:48Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.45.3</generator>
	<entry>
		<id>https://camokathomelab.servebeer.com/mediawiki/index.php?title=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B8%D0%BF%D0%B0&amp;diff=5320&amp;oldid=prev</id>
		<title>imported&gt;Mercury: /* {{якорь|dynamic_cast}} Операция {{cpp|dynamic_cast}} */</title>
		<link rel="alternate" type="text/html" href="https://camokathomelab.servebeer.com/mediawiki/index.php?title=%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D0%B4%D0%B5%D0%BD%D0%B8%D0%B5_%D1%82%D0%B8%D0%BF%D0%B0&amp;diff=5320&amp;oldid=prev"/>
		<updated>2026-02-02T01:22:20Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;{{якорь|dynamic_cast}} Операция {{cpp|dynamic_cast}}&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;&amp;#039;&amp;#039;&amp;#039;Приведе́ние (преобразование) ти́па&amp;#039;&amp;#039;&amp;#039; ({{lang-en|type conversion}}, {{lang-en2|typecasting}}) — в [[Информатика|информатике]] преобразование значения одного [[тип данных|типа]] в значение другого типа.&lt;br /&gt;
&lt;br /&gt;
== Описание ==&lt;br /&gt;
Выделяют приведения типов:&lt;br /&gt;
* явные ({{lang-en|explicit}});&lt;br /&gt;
* неявные ({{lang-en|implicit}} &amp;#039;&amp;#039;cast, coercion&amp;#039;&amp;#039;).&lt;br /&gt;
&lt;br /&gt;
Явное приведение задаётся [[программист]]ом в тексте программы с помощью:&lt;br /&gt;
* конструкции языка;&lt;br /&gt;
* встроенных [[Функция (программирование)|функций]], принимающей значение одного типа и возвращающей значение другого типа.&lt;br /&gt;
&lt;br /&gt;
Неявное приведение выполняется [[транслятор]]ом ([[компилятор]]ом или [[интерпретатор]]ом) по правилам, описанным в стандарте языка. Стандарты большинства языков запрещают неявные преобразования.&lt;br /&gt;
&lt;br /&gt;
В  [[Объектно-ориентированное программирование|объектно-ориентированных]] языках, таких как [[C++]], механизм [[наследование (программирование)|наследования]] реализуется посредством приведения типа указателя или ссылки на текущий объект к базовому классу (в [[типобезопасность|типобезопасных]], таких как [[OCaml]], понятие о приведении типов отсутствует принципиально, и допустимость обращения к компоненту подтипа контролируется механизмом [[Типобезопасность|проверки согласования типов]] на этапе компиляции, а в машинном коде остаётся прямое обращение).&lt;br /&gt;
&lt;br /&gt;
== Неявное приведение типа ==&lt;br /&gt;
&lt;br /&gt;
=== Неявное приведение типа в языках C/C++ ===&lt;br /&gt;
Неявное приведение типов происходит в следующих случаях&amp;lt;ref&amp;gt;cppreference.com. [http://en.cppreference.com/w/cpp/language/implicit_cast Implicit conversions] {{Wayback|url=http://en.cppreference.com/w/cpp/language/implicit_cast |date=20141218154009 }}.&amp;lt;/ref&amp;gt;:&lt;br /&gt;
* после вычисления операндов бинарных арифметических, логических, битовых операций, операций сравнения, а также 2-го или 3-го операнда операции «?:»; значения операндов приводятся к одинаковому типу;&lt;br /&gt;
* перед выполнением присваивания;&lt;br /&gt;
* перед передачей аргумента функции;&lt;br /&gt;
* перед возвратом функцией возвращаемого значения;&lt;br /&gt;
* после вычисления выражения конструкции {{cpp|1=switch}} значение приводится к целочисленному типу;&lt;br /&gt;
* после вычисления выражений конструкций {{cpp|1=if}}, {{cpp|1=for}}, {{cpp|1=while}}, {{cpp|1=do}}-{{cpp|1=while}} значение приводится к типу {{cpp|1=bool}}.&lt;br /&gt;
Например, при выполнении бинарной арифметической операции значения операндов приводятся к одному типу. При наследовании указатели производного класса приводятся к указателям базового класса.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим пример на языке [[Си (язык программирования)|C]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
double  d;  // вещественный тип&lt;br /&gt;
long    l;  // целый тип&lt;br /&gt;
int     i;  // целый тип&lt;br /&gt;
&lt;br /&gt;
if ( d &amp;gt; i )      d  = i;&lt;br /&gt;
if ( i &amp;gt; l )      l  = i;&lt;br /&gt;
if ( d == l )     d *= 2;&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При выполнении операций сравнения и при присваивании переменные разных типов неявно приводятся к одному типу.&lt;br /&gt;
&lt;br /&gt;
При неявных преобразованиях возможны побочные эффекты. Например, при приведении числа вещественного типа к целому типу дробная часть отсекается ([[округление]] не выполняется)&amp;lt;ref&amp;gt;open-std.org [http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf ISO/IEC 9899:2018 C Programming Language Standard (C18)] {{Wayback|url=http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2310.pdf |date=20200722132012 }} 6.3.1.4 Real floating and integer.&amp;lt;/ref&amp;gt;. При обратном преобразовании возможно понижение точности из-за различий в [[Число#Представление чисел в памяти компьютера|представлении]] вещественных и целочисленных чисел. Например, в переменной типа {{cpp|1=float}} ([[число с плавающей точкой]] [[Число одинарной точности|одинарной точности]] по стандарту [[IEEE 754]]), нельзя сохранить число {{formatnum:16777217}} без потери точности, а в 32-битной переменной целого типа {{cpp|1=int}} — можно. Из-за потери точности операции сравнения одного и того же числа, представленного целым и вещественным типами (например, {{cpp|1=int}} и {{cpp|1=float}}), могут давать ложные результаты (числа могут быть не равны).&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;stdio.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
int main ( void )&lt;br /&gt;
{&lt;br /&gt;
   int   i_value = 16777217;&lt;br /&gt;
   float f_value = 16777216.0;&lt;br /&gt;
   printf( &amp;quot;The integer is:%d\n&amp;quot;, i_value );&lt;br /&gt;
   printf( &amp;quot;The float is:  %f\n&amp;quot;, f_value );&lt;br /&gt;
   printf( &amp;quot;Their equality:%d\n&amp;quot;, i_value == f_value );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Приведённый код выведет следующее, если размер {{cpp|1=int}} — 32 бита и компилятор поддерживает стандарт [[IEEE 754]]:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
 The integer is: 16777217&lt;br /&gt;
 The float is: 16777216.000000&lt;br /&gt;
 Their equality: 1&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Явное приведение типа ==&lt;br /&gt;
&lt;br /&gt;
=== Приведения типов в языке C ===&lt;br /&gt;
Для явного приведения типов имя типа указывается в круглых скобках перед переменной или выражением. Рассмотрим пример.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
int X;&lt;br /&gt;
int Y = 200;&lt;br /&gt;
char C = 30;&lt;br /&gt;
X = (int)C * 10 + Y; // переменная С приводится к типу int&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Для вычисления последнего выражения [[компилятор]] выполняет примерно следующие действия:&lt;br /&gt;
* сначала переменная {{cpp|1=C}} символьного типа {{cpp|1=char}} явно приводится к целочисленному типу {{cpp|1=int}} путём расширения [[Разрядность|разрядности]];&lt;br /&gt;
* выполняется вычисление операндов для операции умножения. Левый операнд имеет тип {{cpp|1=int}}. Правый операнд — константа &amp;lt;code&amp;gt;10&amp;lt;/code&amp;gt;, а такие константы по умолчанию имеют тип {{cpp|1=int}}. Так как оба операнда оператора «&amp;lt;tt&amp;gt;*&amp;lt;/tt&amp;gt;» имеют тип {{cpp|1=int}}, неявное приведение типов не выполняется. Результат умножения тоже имеет тип {{cpp|1=int}};&lt;br /&gt;
* выполняется вычисление операндов операции сложения. Левый операнд — результат умножения имеет тип {{cpp|1=int}}. Правый операнд — переменная {{cpp|1=Y}} имеет тип {{cpp|1=int}}. Так как оба операнда оператора «&amp;lt;tt&amp;gt;+&amp;lt;/tt&amp;gt;» имеют тип {{cpp|1=int}}, неявное приведение к общему типу не выполняется. Результат сложения тоже имеет тип {{cpp|1=int}};&lt;br /&gt;
* выполнение присваивания. Левый операнд — переменная {{cpp|1=X}} имеет тип {{cpp|1=int}}. Правый операнд — результат вычисления выражения, записанного справа от знака «&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;», тоже имеет тип {{cpp|1=int}}. Так как оба операнда оператора «&amp;lt;tt&amp;gt;=&amp;lt;/tt&amp;gt;» имеют одинаковый тип, неявное приведение типов не выполняется.&lt;br /&gt;
&lt;br /&gt;
Но даже при этом возможны ошибки. Тип {{cpp|1=char}} может быть как знаковым ({{cpp|1=signed char}}), так и беззнаковым ({{cpp|1=unsigned char}}); результат зависит от реализации компилятора и такое поведение разрешено стандартом. Значение беззнакового типа {{cpp|1=char}} при преобразовании к знаковому типу {{cpp|1=int}} может оказаться отрицательным из-за особенностей реализации машинных инструкций на некоторых [[процессор]]ах. Чтобы избежать неоднозначностей, рекомендуется явно указывать знаковость для типа {{cpp|1=char}}.&lt;br /&gt;
&lt;br /&gt;
=== Приведения типов в языке C++ ===&lt;br /&gt;
В языке [[C++]] существует пять операций для явного приведения типа. Первая операция — круглые скобки ({{cpp|1=(type_to)expression_from}}) поддерживается для сохранения совместимости с [[Си (язык программирования)|C]]. Остальные четыре операции записываются в виде&lt;br /&gt;
&lt;br /&gt;
 &amp;#039;&amp;#039;&amp;#039;xxx_cast&amp;#039;&amp;#039;&amp;#039;&amp;lt; type_to &amp;gt;( expression_from )&lt;br /&gt;
&lt;br /&gt;
Рассмотрим пример.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
y = static_cast&amp;lt; signed short &amp;gt;( 65534 ); // переменной y будет присвоено значение -2&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Громоздкие [[зарезервированное слово|ключевые слова]] являются напоминанием программисту о том, что приведение типа чревато проблемами.&lt;br /&gt;
&lt;br /&gt;
==== {{якорь|static_cast}} Операция {{cpp|static_cast}} ====&lt;br /&gt;
{{main|static_cast}}&lt;br /&gt;
Назначение: допустимые приведения типов.&lt;br /&gt;
&lt;br /&gt;
Операция {{cpp|1=static_cast}} аналогична операции «круглые скобки» с одним исключением: она не выполняет приведение указателей на неродственные типы (для этого применяется операция {{cpp|1=reinterpret_cast}}).&lt;br /&gt;
&lt;br /&gt;
Применение:&lt;br /&gt;
* преобразование между числовыми и enum, в том числе если неявное преобразование невозможно ({{cpp|int → enum class}}) или приводит к предупреждению «Возможная потеря точности» ({{cpp|double → float}});&lt;br /&gt;
* приведение указателей к типу {{cpp|1=void*}} и наоборот;&lt;br /&gt;
* приведение указателей на производные типы к указателям на базовые типы и наоборот;&lt;br /&gt;
* выбор одной из нескольких [[перегрузка функций|перегруженных функций]];&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
bool myLess(const wchar_t*, const wchar_t*);&lt;br /&gt;
bool myLess(const std::wstring&amp;amp;, const std::wstring&amp;amp;);&lt;br /&gt;
&lt;br /&gt;
std::vector&amp;lt;std::wstring&amp;gt; list;&lt;br /&gt;
std::sort(list.begin(), list.end(), static_cast&amp;lt;bool(*)(const std::wstring&amp;amp;, const std::wstring&amp;amp;)&amp;gt;(myLess));&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* явный вызов конструктора с одним аргументом или перегруженной операции приведения типа;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct Type {&lt;br /&gt;
   // конструктор с одним аргументом для приведения типа int к типу Type&lt;br /&gt;
   Type ( int );&lt;br /&gt;
&lt;br /&gt;
   // перегруженная операция для приведения типа Type к типу double&lt;br /&gt;
   operator double () const;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
int main () {&lt;br /&gt;
   Type x, y;&lt;br /&gt;
   int i;&lt;br /&gt;
   double d;&lt;br /&gt;
&lt;br /&gt;
   // вызов конструктора с одним аргументом&lt;br /&gt;
   x = y + static_cast&amp;lt; Type &amp;gt;( i );&lt;br /&gt;
&lt;br /&gt;
   // вызов перегруженной операции приведения типа&lt;br /&gt;
   d = static_cast&amp;lt; double &amp;gt;( x );&lt;br /&gt;
&lt;br /&gt;
   return 0;&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
: конструктор может иметь большее число аргументов, но для них должны быть заданы значения по умолчанию;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
struct Type {&lt;br /&gt;
   // конструктор с несколькими аргументами для приведения типа int к типу Type;&lt;br /&gt;
   // для 2-го и последующих аргументов заданы значения по умолчанию&lt;br /&gt;
   Type ( int, int = 10, float = 0.0 );&lt;br /&gt;
};&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
* приведение типа в [[шаблоны C++|шаблонах]] (компилятор уже при специализации шаблона решает, какие операции использовать);&lt;br /&gt;
* приведение операндов [[Тернарная условная операция|тернарной условной операции]] «&amp;lt;code&amp;gt;?:&amp;lt;/code&amp;gt;» к одному типу (значения 2-го и 3-го операндов должны иметь одинаковый тип);&lt;br /&gt;
&lt;br /&gt;
Ограничения на &amp;lt;code&amp;gt;expression_from&amp;lt;/code&amp;gt;: нет.&lt;br /&gt;
&lt;br /&gt;
Ограничения на &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt;: должен существовать способ преобразования значения выражения &amp;lt;code&amp;gt;expression_from&amp;lt;/code&amp;gt; к типу &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt;, с помощью &amp;lt;code&amp;gt;operator type_to&amp;lt;/code&amp;gt; или конструктора.&lt;br /&gt;
&lt;br /&gt;
Производит ли операция {{cpp|1=static_cast}} код: в общем случае да (например, вызов перегруженной операции приведения типа или конструктора).&lt;br /&gt;
&lt;br /&gt;
Источники логических ошибок: зависят от того, что собираетесь делать операцией. Возможны переполнения, выход за диапазон и даже (для преобразования указателей) порча памяти.&lt;br /&gt;
&lt;br /&gt;
Пути избавления: зависят от задачи, и часто избавляться не нужно.&lt;br /&gt;
&lt;br /&gt;
Примеры.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Получить процент попаданий.&lt;br /&gt;
double hitpercent (&lt;br /&gt;
   const int aHitCount, // число попаданий&lt;br /&gt;
   const int aShotCount // число выстрелов&lt;br /&gt;
) {&lt;br /&gt;
   if ( aShotCount == 0 ) return 0.0;&lt;br /&gt;
   // Приведение типов к double выполняется для выполнения вещественного (не целочисленного) деления&lt;br /&gt;
   return static_cast&amp;lt; double &amp;gt;( aHitCount * 100 ) / static_cast&amp;lt; double &amp;gt;( aShotCount );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// следующие строчки эквивалентны&lt;br /&gt;
&lt;br /&gt;
// использование операции static_cast&lt;br /&gt;
string s = static_cast&amp;lt; string &amp;gt;( &amp;quot;Hello!&amp;quot; );&lt;br /&gt;
// вызов конструктора с одним аргументом&lt;br /&gt;
string s = string( &amp;quot;Hello!&amp;quot; );&lt;br /&gt;
// использование операции «круглые скобки»&lt;br /&gt;
string s = (string) &amp;quot;Hello!&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
string s = static_cast&amp;lt; string &amp;gt;( 5 ); // не компилируется, компилятор не может найти подходящий конструктор&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== {{якорь|dynamic_cast}} Операция {{cpp|dynamic_cast}} ====&lt;br /&gt;
{{main|Dynamic_cast}}&lt;br /&gt;
Назначение: приведение вниз по иерархии наследования, с особым поведением, если объект не имеет нужного типа. Используется именно в случаях, когда программист не уверен в типе.&lt;br /&gt;
&lt;br /&gt;
Операция получает информацию о типе объекта &amp;lt;code&amp;gt;expression_from&amp;lt;/code&amp;gt; с помощью [[RTTI]]. Если тип будет &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt; или его подтипом, приведение выполняется. Иначе:&lt;br /&gt;
* для указателей возвращается [[NULL (Си)|NULL]];&lt;br /&gt;
* для ссылок создаётся [[обработка исключений|исключение]] {{cpp|1=std::bad_cast}}.&lt;br /&gt;
&lt;br /&gt;
Ограничения на &amp;lt;code&amp;gt;expression_from&amp;lt;/code&amp;gt;: выражение должно быть ссылкой или указателем на объект, имеющий хотя бы одну [[виртуальный метод|виртуальную функцию]].&lt;br /&gt;
&lt;br /&gt;
Ограничения на &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt;: любой другой виртуальный, также соответственно ссылка или указатель.&lt;br /&gt;
&lt;br /&gt;
Производит ли операция {{cpp|1=dynamic_cast}} код: да.&lt;br /&gt;
&lt;br /&gt;
Логические ошибки возможны, если операции передать аргумент, не имеющий тип &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt;, и не проверить указатель на равенство {{cpp|1=NULL}} (соответственно не обработать исключение {{cpp|1=std::bad_cast}}).&lt;br /&gt;
&lt;br /&gt;
Пути избавления: продуманная объектная система. Иногда (например, в обработке событий пользовательского интерфейса) dynamic_cast используют только как дополнительную самопроверку, когда и без того известно, какого типа объект, спровоцировавший событие.&lt;br /&gt;
&lt;br /&gt;
==== {{якорь|const_cast}} Операция {{cpp|const_cast}} ====&lt;br /&gt;
Назначение: снятие/установка модификатора(ов) {{cpp|1=const}}, {{cpp|1=volatile}} и/или {{cpp|1=mutable}}. Часто это применяется, чтобы обойти неудачную архитектуру программы или библиотеки, для стыковки с другими языками, для передачи информации через обобщённые указатели &amp;lt;code&amp;gt;void*&amp;lt;/code&amp;gt;, для одновременного написания const- и не-const-версии функции&amp;lt;ref name=&amp;quot;weekly&amp;quot;&amp;gt;{{Cite web |url=https://www.youtube.com/watch?v=iuLwHoMFP_Y |title=C++ Weekly - Ep 283 - Stop Using const_cast! - YouTube&amp;lt;!-- Заголовок добавлен ботом --&amp;gt; |access-date=2021-08-20 |archive-date=2021-08-20 |archive-url=https://web.archive.org/web/20210820190607/https://www.youtube.com/watch?v=iuLwHoMFP_Y |url-status=live }}&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ограничения на &amp;lt;code&amp;gt;expression_from&amp;lt;/code&amp;gt;: выражение должно возвращать ссылку или указатель.&lt;br /&gt;
&lt;br /&gt;
Ограничения на &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt;: тип &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt; должен совпадать с типом выражения &amp;lt;code&amp;gt;expression_from&amp;lt;/code&amp;gt; с точностью до модификатора(ов) {{cpp|1=const}}, {{cpp|1=volatile}} и {{cpp|1=mutable}} .&lt;br /&gt;
&lt;br /&gt;
Производит ли операция {{cpp|1=const_cast}} код: нет.&lt;br /&gt;
&lt;br /&gt;
Источники логических ошибок: программа может изменить неизменяемый объект. Иногда это может привести к [[SIGSEGV|ошибке сегментации]], иногда подпрограмма может не ожидать&amp;lt;ref name=&amp;quot;weekly&amp;quot; /&amp;gt;, что память, которую она предоставила для чтения, вдруг изменили.&lt;br /&gt;
&lt;br /&gt;
Пути избавления: просчитанная const-корректность и удачный API: с Си++17 {{cpp|string.data()}} получила версию без const. С [[Си++14]] — общая шаблонная функция, возвращающая {{cpp|decltype(auto)}}, и функции с const и без вызывают её&amp;lt;ref name=&amp;quot;weekly&amp;quot; /&amp;gt;. С [[Си++23]] эту функцию сразу можно использовать как метод.&lt;br /&gt;
&lt;br /&gt;
Для примера рассмотрим код [[Библиотека (программирование)#Динамические библиотеки|динамической библиотеки]].&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;string&amp;gt; // string&lt;br /&gt;
using namespace std;&lt;br /&gt;
&lt;br /&gt;
namespace&lt;br /&gt;
{&lt;br /&gt;
   string s = &amp;quot;Wikipedia&amp;quot;; // Глобальная переменная&lt;br /&gt;
   // метод string::c_str() возвращает указатель типа const char *&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
typedef char * PChar;&lt;br /&gt;
&lt;br /&gt;
void __declspec( dllexport ) WINAPI SomeDllFunction ( PChar &amp;amp; rMessage )&lt;br /&gt;
{&lt;br /&gt;
   // преобразование char const * в char *&lt;br /&gt;
   rMessage = const_cast&amp;lt; char * &amp;gt;( s.c_str() );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
При загрузке библиотеки в память [[Процесс (информатика)|процесса]] создаёт новый сегмент данных, в котором размещаются глобальные переменные.&lt;br /&gt;
Код функции {{cpp|1=SomeDllFunction()}} находится в библиотеке и при вызове возвращает указатель на строковые данные. Операция {{cpp|1=const_cast}} используется для удаления модификатора {{cpp|1=const}}.&lt;br /&gt;
&lt;br /&gt;
==== {{якорь|reinterpret_cast}} Операция {{cpp|reinterpret_cast}} ====&lt;br /&gt;
Назначение: [[каламбур типизации]] — назначение ячейке памяти другого типа (не обязательно совместимого с данным) с сохранением битового представления.&lt;br /&gt;
&lt;br /&gt;
Объект, возвращаемый выражением &amp;lt;code&amp;gt;expression_from&amp;lt;/code&amp;gt;, рассматривается как объект типа &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Ограничения на &amp;lt;code&amp;gt;expression_from&amp;lt;/code&amp;gt;: выражение должно возвращать значение порядкового типа (любой из целых, логический {{cpp|1=bool}} или перечислимый {{cpp|1=enum}}), указатель или ссылку.&lt;br /&gt;
&lt;br /&gt;
Ограничения на &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt;:&lt;br /&gt;
* Если &amp;lt;code&amp;gt;expression_from&amp;lt;/code&amp;gt; возвращает значение порядкового типа или указатель, тип &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt; может быть порядковым типом или указателем.&lt;br /&gt;
* Если &amp;lt;code&amp;gt;expression_from&amp;lt;/code&amp;gt; возвращает ссылку, тип &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt; должен быть ссылкой.&lt;br /&gt;
&lt;br /&gt;
Производит ли операция {{cpp|1=reinterpret_cast}} код: нет.&lt;br /&gt;
&lt;br /&gt;
Источники логических ошибок. Объект, возвращаемый выражением &amp;lt;code&amp;gt;expression_from&amp;lt;/code&amp;gt;, может не иметь типа &amp;lt;code&amp;gt;type_to&amp;lt;/code&amp;gt;. Нет никакой возможности проверить это, всю ответственность за корректность преобразования программист берёт на себя.&lt;br /&gt;
&lt;br /&gt;
Пути избавления: поскольку функция предназначена для работы на низком уровне и обхода ошибок чужой архитектуры, практически нет. Одну из задач — низкоуровневую работу с битами и байтами памяти — можно и нужно заменять на функцию {{cpp|bit_cast}} Си++20.&lt;br /&gt;
&lt;br /&gt;
Рассмотрим примеры.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;cpp&amp;quot;&amp;gt;&lt;br /&gt;
// Возвращает true, если число x конечное.&lt;br /&gt;
// Возвращает false, если число x равно ∞ или NaN.&lt;br /&gt;
bool isfinite ( double const x )&lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
   // преобразование double const -&amp;gt; uint64_t const &amp;amp;&lt;br /&gt;
   uint64_t const &amp;amp; y = reinterpret_cast&amp;lt; uint64_t const &amp;amp; &amp;gt;( x );&lt;br /&gt;
&lt;br /&gt;
   return ( ( y &amp;amp; UINT64_C( 0x7FF0000000000000 ) ) != UINT64_C( 0x7FF0000000000000 ) );&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// попытка получения адреса временного значения&lt;br /&gt;
long const &amp;amp; y = reinterpret_cast&amp;lt; long const &amp;amp; &amp;gt;( x + 5.0 );&lt;br /&gt;
// ошибка: выражение x + 5.0 не является ссылкой&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== См. также ==&lt;br /&gt;
* [[Dynamic cast]]&lt;br /&gt;
* [[Динамическая идентификация типа данных]] (RTTI)&lt;br /&gt;
* [[Типизация данных]]&lt;br /&gt;
* [[Каламбур типизации]]&lt;br /&gt;
&lt;br /&gt;
== Примечания ==&lt;br /&gt;
{{Примечания}}&lt;br /&gt;
&lt;br /&gt;
== Ссылки ==&lt;br /&gt;
* Robert C. Seacord [https://web.archive.org/web/20140921015632/https://www.securecoding.cert.org/confluence/display/seccode/INT02-C.+Understand+integer+conversion+rules ПINT02-C. Understand integer conversion rules]{{ref|en}}, cert.org&lt;br /&gt;
&lt;br /&gt;
{{нет источников|дата=2015-01-03}}&lt;br /&gt;
{{перевести|en|Type conversion}}&lt;br /&gt;
&lt;br /&gt;
[[Категория:Типы данных]]&lt;br /&gt;
[[Категория:Концепции языков программирования]]&lt;br /&gt;
[[Категория:Статьи с примерами кода C++]]&lt;br /&gt;
[[Категория:Операции в программировании]]&lt;/div&gt;</summary>
		<author><name>imported&gt;Mercury</name></author>
	</entry>
</feed>