c++ reinterpret cast和c style cast之间的区别

标签 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!";
}

输出:

Same Thing!

我想知道这两种类型转换方法有什么区别。 此外,如果您可以指定(通过示例)static_cast、dynamic_cast 和您知道的其他类型的转换之间的区别(即保持尽可能低的级别并尽可能接近汇编语言)。

static_cast
dynamic_cast
const_cast
reinterpret_cast
C-style cast (type)value
Function-style cast type(value)

谢谢。

请阅读 P.S. 我从上面的例子中知道 reinterpret_cast 将 keyStr[29] 的地址分配给 int 指针 在汇编中将转化为:

lea eax, [keyStr+1D]
mov [reCast], eax

换句话说,reinterpret_cast 在低级别的预期中一点也不危险,因为它不会修改原始数据。

我想知道其他转换方法在底层的表现如何。 因此,例如,一个对象,以低级方式,只是一个保存地址的变量。 如果该对象是编译器随后如何解释该地址以及它如何偏移它的类型。(这正是我不感兴趣的,在汇编中,我不太关心该变量是否包含一个值,一个指针或一个对象(即另一个指针))。 另一件可能相同的事情是 int 和 int* 或 unsigned int 和 int 之间的区别;所有 4 个声明生成相同的汇编指令。 ( push value ) 或者 (sub esp-(length of int) && mov esp, value) 我希望这能澄清问题以及为什么我将其标记为“低级代码”和“程序集”

附言在这个程序中,我试图创建我不关心不可移植性或其他高级内容。我正在尝试尽可能低的水平并尽可能接近汇编语言。这意味着,对于这个程序,内存只是内存(即 0 和 1 位),类型并不重要(例如,我不在乎内存地址:0x123 是“int”类型还是“float”类型,它只是“数据”)

最佳答案

reinterpret_castconst_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

一个异常(exception):C 风格的转换可以忽略类之间的私有(private)和 protected 继承关系,假装它们具有公共(public)继承关系。

C 风格的强制转换在 C++ 中通常不是首选,因为它不太明确您想要发生的事情。

关于c++ reinterpret cast和c style cast之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27359961/

相关文章:

c - 我如何跟踪内存分配?

c++ - 高阶位——把它们变成 uint64_t 变成 uint8_t

assembly - x86_64 程序集 : effects of the interrupt flag and TPR register

C++ 虚函数前向声明

c++ - 重载成员函数的成员函数指针

c++ - 有没有办法以毫秒为单位计算程序的时间复杂度?

C++ 头文件 - 困惑!

c++ - fseek 写入值时回到文件末尾

objective-c - 开发人员在 Objective-C 中使用 C 函数是否有技术原因

java - 任务 ':app:transformClassesWithDexForDebug' 执行失败 dex 进程返回代码 1