Fre*_*sco 4 c c++ assembly casting low-level-code
码:
char keyStr[50]={ 0x5F, 0x80 /* bla bla */ };
uint32_t* reCast = reinterpret_cast< uint32_t* >( &keyStr[29] );
uint32_t* reCast2 = ( uint32_t* )&keyStr[29];
if( reCast == reCast2 ){
cout << "Same Thing!";
}
Run Code Online (Sandbox Code Playgroud)
输出:
一样!
我想知道这两种铸造方法有什么区别。另外,如果您可以(通过示例)指定static_cast,dynamic_cast和您知道的其他类型的转换之间的差异(即,保持较低的级别并尽可能接近汇编语言)。
static_cast
dynamic_cast
const_cast
reinterpret_cast
C-style cast (type)value
Function-style cast type(value)
Run Code Online (Sandbox Code Playgroud)
谢谢。
请阅读我从上面的示例中了解到的PS,reinterpret_cast将int指针分配给int指针keyStr [29]的地址在汇编中将转换为:
lea eax, [keyStr+1D]
mov [reCast], eax
Run Code Online (Sandbox Code Playgroud)
因此,换句话说,从低级别的角度来看,reinterpret_cast根本没有危险,因为它不会修改原始数据。
我想知道其他铸造方法在低水平方面的表现。因此,例如,对象以低级方式仅仅是保存地址的变量。以及该对象的类型是编译器随后如何解释该地址及其偏移量。对象(即另一个指针))。另一件事可能是相同的,就是int和int *或unsigned int和int之间的区别;所有4个声明都生成相同的汇编指令。(推送值)或(sub esp-(int的长度)&& mov esp,值)我希望这可以澄清问题,以及为什么我将其标记为“低级代码”和“汇编”
PS在此程序中,我尝试创建我不在乎非可移植性或其他高级内容。我正在尝试尽可能降低级别,并尽可能接近汇编语言。这意味着,对于该程序,内存只是内存(即0和1位),类型并不重要(例如,我不在意内存地址:0x123是“ int”类型还是“ float”类型,只是“数据”)
reinterpret_cast
并且const_cast
是解决C ++类型系统的方法。如您所注意reinterpret_cast
,这通常转化为很少或没有汇编代码。
static_cast
最尊重C ++类型系统。它可以将数字从一种类型转换为另一种类型,或调用构造函数或调用转换函数。或对于派生到基本的转换,可能涉及在vtable中添加字节偏移量和/或查找。 static_cast
还可以通过将指针或引用从非虚拟基本类型“下垂”到派生类型,并可能减去字节偏移量来弯曲类型系统的规则。
然后是指向成员的指针。它们可能不在这里,但是static_cast
对它们所做的事情或多或少类似于类指针转换。
dynamic_cast
更严格地尊重C ++类型系统。它以有用的形式在运行时检查指针/引用是否实际上指向/引用了指定类型的对象。它通常在后台调用魔术库函数。
具有一个参数的函数样式强制转换与C样式强制转换具有完全相同的效果。(带有多个参数,函数样式的强制转换必须是使用类构造函数的临时初始化。)C样式的强制转换从以下列表中进行了第一件事:
const_cast
static_cast
static_cast
然后一个const_cast
reinterpret_cast
,或reinterpret_cast
然后一个const_cast
一个例外:C样式强制转换可以忽略类之间的私有继承关系和受保护继承关系,假装它们具有公共继承关系。
C样式强制转换通常在C ++中不是首选,因为它对要发生的事情不太明确。