ОК, поэтому я попытался сделать это
int b;
char x = 'a';
//Case 1
b = static_cast<int>(x);
std::cout<<"B is : "<<b<<std::endl;
//Case 2
b = *(int*)&x;
std::cout<<"B is changed as :: "<< b <<std::endl;
Теперь я знаю, что в случае 2, первый байт x
интерпретируется так, что это целое число, а битовая комбинация копируется в b
который дает некоторый мусор, а в случае 1 он просто конвертирует значение из char
в int
,
Кроме того, есть ли различия между этими двумя?
Первый просто преобразует значение: int b = x;
такой же как int b = static_cast<int>(x);
,
Второй случай делает вид, что есть int
жить в том месте, где на самом деле x
живет, а потом пытается это прочитать int
, Это прямое неопределенное поведение. (Например, int
может занимать больше места, чем char
или это может быть char
живет по адресу, где нет int
может когда-нибудь жить.)
2-й случай — это приведение в стиле C (как обозначено bhuang3), но это не C-стиль, эквивалентный случаю 1. Это было бы
b = (int)x;
, И C ++ эквивалент случая 2 будет b = *reinterpret_cast<int*>(&x);
В любом случае, случай 2 — неопределенное поведение, потому что x занимает один байт, в то время как принудительное чтение данных типа int по адресу x либо приведет к ошибке сегментации (ошибка шины в некоторых системах), если он не по юридическому адресу для int
или он просто прочитает следующие 3 байта, значения которых мы не знаем, что они есть. Таким образом, он читает «мусор», как вы заметили.
static_cast
не обеспечивает проверки во время выполнения, которая используется, если вы знаете, что ссылаетесь на объект определенного типа.
Второй случай на самом деле c-style cast