Я понимаю это reinterpret_cast
опасно, я просто делаю это для тестирования его. У меня есть следующий код:
int x = 0;
double y = reinterpret_cast<double>(x);
Когда я пытаюсь скомпилировать программу, она дает мне ошибку при высказывании
недопустимый бросок от типа 'плавает' для ввода 'дважды
Что продолжается? Я думал reinterpret_cast
жулик был брошен, что Вы могли использовать для преобразования яблок в подводные лодки, почему этот простой бросок не скомпилирует?
Присваивая y значению, возвращаемому преобразованием, вы на самом деле не преобразовываете значение x
, а преобразуете его. То есть y
не указывает на x
и не делает вид, что указывает на float. Преобразование создает новое значение типа float
и присваивает ему значение из x
. Есть несколько способов выполнить это преобразование в C ++, среди них:
int main()
{
int x = 42;
float f = static_cast<float>(x);
float f2 = (float)x;
float f3 = float(x);
float f4 = x;
return 0;
}
Единственная реальная разница, заключающаяся в том, что последнее (неявное преобразование) генерирует диагностику компилятора при более высоких уровнях предупреждений. Но все они функционально выполняют одно и то же - и во многих случаях фактически то же самое, что и в одном и том же машинном коде.
Теперь, если вы действительно хотите представить, что x
- это число с плавающей запятой, тогда вы действительно хотите преобразовать x
, сделав следующее:
#include <iostream>
using namespace std;
int main()
{
int x = 42;
float* pf = reinterpret_cast<float*>(&x);
(*pf)++;
cout << *pf;
return 0;
}
Вы можете увидеть, насколько опасно это. Фактически, когда я запускаю это на своей машине, результат будет 1
, что определенно не равно 42 + 1.
В C ++ reinterpret_cast
может выполнять только определенный набор преобразований, явно указанных в спецификации языка. Короче говоря, reinterpret_cast
может выполнять только преобразования указателя в указатель и преобразования ссылки в ссылку (плюс преобразования указателя в целое число и преобразования из целого числа в указатель). Это согласуется с намерением, выраженным в самом названии приведения: оно предназначено для использования для переинтерпретации указателя / ссылки.
То, что вы пытаетесь сделать, не является переосмыслением. Если вы хотите переинтерпретировать int
как double
, вам придется преобразовать его в ссылочный тип
double y = reinterpret_cast<double&>(x);
, хотя эквивалентная переинтерпретация на основе указателя, вероятно, более явна
double y = *reinterpret_cast<double*>(&x); // same as above
Однако обратите внимание, что хотя reinterpret_cast
может преобразовывать типы ссылок / указателей, фактическая попытка чтения данных через результирующую ссылку / указатель приводит к неопределенному поведению.
И в любом случае это, конечно, не имеет особого смысла на платформе с int
и double
разного размера (поскольку в случае большего double
вы будете читать за пределами памяти, занятой x
).
Итак, в конце концов, все сводится к тому, чего вы пытались достичь. Переосмысление памяти? См. Выше. Какое-то более осмысленное преобразование int
в двойное
? В таком случае reinterpret_cast
вам здесь не поможет.
reinterpret_cast не является общим составом. В соответствии со спецификацией C ++ 03, раздел 5.2.10.1:
Конверсии, которые могут быть выполнены явно с помощью reinterpret_cast, перечислены ниже. Никакое другое преобразование не может быть выполнено явно с помощью reinterpret_cast.
И в списке нет ничего, что описывало бы преобразование между целочисленными типами и типами с плавающей запятой (или между целочисленными типами, даже это недопустимо reinterpret_cast
)
Приведение типа Reinterpret позволяет вам интерпретировать блок памяти как другой тип. Это должно быть выполнено с указателями или ссылками :
int x = 1;
float & f = reinterpret_cast<float&>(x);
assert( static_cast<float>(x) != f ); // !!
Другое дело, что это на самом деле довольно опасное приведение, не только из-за странных значений, получаемых как результаты, или из-за того, что утверждение выше не дает сбоя. , но поскольку если типы имеют разные размеры и вы переинтерпретируете типы «исходный» на «целевой», любая операция с переинтерпретированной ссылкой / указателем будет обращаться к байтам sizeof (destination)
. Если sizeof (destination)> sizeof (source)
, тогда это выйдет за пределы фактической памяти переменных, потенциально убивая ваше приложение или перезаписывая другие переменные, кроме источника или назначения:
struct test {
int x;
int y;
};
test t = { 10, 20 };
double & d = reinterpret_cast<double&>( t.x );
d = 1.0/3.0;
assert( t.x != 10 ); // most probably at least.
assert( t.y != 20 );
reinterpret_cast
лучше всего использовать для указателей. Таким образом, указатель на один объект можно превратить в "подводную лодку".
Из msdn:
Оператором reinterpret_cast может быть используемый для преобразования, например, char* в int*, или One_class* to Несвязанный_класс*, которые по своей природе являются небезопасно.
Результат reinterpret_cast нельзя безопасно использовать ни для чего кроме как быть брошенным на произвол судьбы оригинальный тип. Другие области применения лучший, непортативный.
Приведение int в double не требует преобразования. Компилятор выполняет присвоение неявно.
reinterpret_cast используется с указателями и ссылками, например, преобразование int *
в double *
.
Для бизнес-данных, если данные являются частными, я бы использовал защищенное соединение, в противном случае достаточно аутентификации форм.
Если вы решите использовать защищенное соединение, обратите внимание, что у меня нет опыта обеспечения безопасности веб-сайтов, я просто отказываюсь от того, с чем столкнулся во время собственного личного опыта. Если я ошибаюсь в любом случае, пожалуйста, не стесняйтесь исправлять меня.
Что делать, чтобы подготовить свой веб-сайт для https. (Нужно ли изменять код/конфигурацию)
Чтобы включить SSL (Secure Sockets Layer) для вашего веб-сайта, необходимо настроить сертификат, код или конфигурацию, которые не изменяются.
Я включил SSL для внутреннего веб-сервера, используя OpenSSL и ActivePerl из этого онлайн-руководства . Если это используется для большей аудитории (моя аудитория была менее 10 человек) и находится в открытом доступе, я предлагаю искать профессиональные альтернативы.
Это SSL и https один и тот же...
Не совсем, но они идут рука об руку! SSL обеспечивает шифрование и расшифровку данных при просмотре веб-сайта, https
- это URI, необходимый для доступа к защищенному веб-сайту. При попытке доступа к http://secure.mydomain.com
появится сообщение об ошибке.
Нужно ли подавать заявку с кем-то, чтобы получить какую-либо лицензию или что-то еще.
Вам нужно получить не лицензию, а сертификат. Можно найти компании, которые предлагают профессиональные услуги с защищенными веб-сайтами, например, VeriSign .
Нужно ли защищать все мои страницы или только страницу входа в систему...
После включения сертификата для mydomain.com
каждая страница под * .mydomain.com
будет защищена.
Если вы пытаетесь преобразовать биты int
в представление double
, вам нужно привести адрес не значение. Вы также должны убедиться, что размеры совпадают:
uint64_t x = 0x4045000000000000;
double y = *reinterpret_cast<double *>(&x);
-121--961175- Это интересно. Возможно, он выполняет неявное преобразование из int в float, прежде чем попытается удвоить состав. типы int и float имеют одинаковый размер в байтах (в зависимости от вашей системы).
Если вы пытаетесь преобразовать биты вашего int
в представление double
, вы необходимо указать адрес , а не значение. Вы также должны убедиться, что размеры совпадают:
uint64_t x = 0x4045000000000000;
double y = *reinterpret_cast<double *>(&x);
Компилятор отвергает написанное вами как бессмыслицу, потому что int
и double
могут быть объектами разных размеров. Таким способом можно добиться того же эффекта, хотя это, безусловно, опасно:
int x = 0;
double y = *reinterpret_cast<double*>(&x);
Это потенциально опасно, потому что если x
и y
имеют разные размеры (скажем, int
- это четыре байта, а double
- восемь байтов), то при разыменовании восьми байтов памяти в & x
для заполнения y
вы получите доступ к четырем байтам x
и четыре байта ... всего, что будет дальше в памяти (возможно, начало y
, или мусор, или что-то еще.)
Если вы хотите преобразовать целое число в двойное, используйте static_cast
, и оно выполнит преобразование.
Если вы хотите получить доступ к битовому шаблону x
, приведите его к некоторому удобному типу указателя (например, byte *
) и получите доступ до sizeof (int) / sizeof (байт)
:
byte* p = reinterpret_cast<byte*>(&x);
for (size_t i = 0; i < sizeof(int); i++) {
// do something with p[i]
}