Если мы используем reinterpret_cast для приведения указателя к указателю, объекта к указателю или указателя к объекту, то приведение осуществляется корректно.
int n = 0;
char* c = reinterpret_cast<char*>(n);
int another_value = reinterpret_cast<int>(c);
Почему reinterpret_cast не позволяет осуществлять приведение на простых форматах?
Такой код не собирается:
int a = 0;
char b = reinterpret_cast<char>(a);
по Страуструпу:
reinterpret_cast управляет преобразованиями между несвязанными типами, например целых в указатели или указателей в другие(несвязанные) указатели.
по Майерсу:
reinterpret_cast предназначен для низкоуровневых приведений, которые порождают зависимые от реализации (то есть непереносимые) результаты, например приведение указателя к int.
Итак, и указатель к указателю, и указатель к int, и int к указателю посредством reinterpret_cast приводятся.
Алена Л. в блоге пишет:
reinterpret_cast - самое нахальное приведение типов. Не портируемо, результат может быть некорректным, никаких проверок не делается. Считается, что вы лучше компилятора знаете как на самом деле обстоят дела, а он тихо подчиняется. Не может быть приведено одно значение к другому значению. Обычно используется, чтобы привести указатель к указателю, указатель к целому, целое к указателю. Умеет также работать со ссылками.
Хорошо, одно значение к другому не может быть приведено. Почему эту возможность не запилили?
reinterpret_cast, как видно из названия, предназначен в первую очередь для выполнения переинтерпретации памяти. То есть когда вы приводите указатель типа T * к указателю типа U *, то предполагается, что вы это делаете для того, чтобы обратиться к памяти исходного объекта типа T, как к памяти объекта типа U. В этом и заключается переинтерпретации памяти. (Разумеется, легальность такого доступа зависит еще от массы посторонних факторов.)
reinterpret_cast также поддерживает аналог такого указательного преобразования, но в варианте со ссылками вместо указателей, т.е. вы можете сделать
T t;
U &u = reinterpret_cast<U &>(t);
и далее получать доступ к памяти объекта t как объекта типа U.
Также на reinterpret_cast дополнительно "повесили" побочную функциональность - приведение между указательными и целыми типами. Все.
А вот чего вы хотели добиться, выполняя reinterpret_cast типа int к типу char - не ясно. Если вам нужна именно переинтерпретация памяти, то это делается так
int a = 0;
char b = reinterpret_cast<char &>(a);
то есть целевой тип должен быть ссылкой.
Ваш же вариант выглядит как обычное преобразование типов, выполняемое static_cast, а не reinterpret_cast. Вся идея разнообразия типов кастов в С++ как раз и сводится к разделению обязанностей между ними с минимальными пересечениями.
Смотрите.
Преобразования бывают двух типов: меняющие внутреннее представление, и не меняющие его.
Преобразование int в double меняет внутреннее представление, double имеет хитрый бинарный layout с мантиссой и порядком. Преобразование целочисленных типов тоже меняет внутреннее представление, если у них разные длины.
А вот смысл reinterpret_cast, наоборот, в том, что он меняет тип объекта с точки зрения компилятора, и (кроме возможных патологических компиляторов) никак не отображается в объектном коде. Вы ж помните, что объект — это просто набор бит в памяти и его тип, позволяющий интерпретировать его? reinterpret_cast просто просит компилятор интерпретировать его по-другому, не меняя сами биты в памяти.
А преобразование, которое умеет делать всё, преобразовывать и числовые типы, и указатели, уже запилили. Это C-style cast. Правда, из-за избыточной мощи его использование не рекомендуется — именно потому, что он может и числа преобразовать, и указатели, и вашего кота, даже если вы этого и не хотели.
Сборка персонального компьютера от Artline: умный выбор для современных пользователей