【问题标题】:What is the diference between static_cast<int>(var) and *(int*)&var?static_cast<int>(var) 和 *(int*)&var 有什么区别?
【发布时间】:2012-12-06 22:13:20
【问题描述】:

好的,所以我尝试这样做

 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 中它只是转换值从charint

除此之外,这两者还有什么不同吗?

【问题讨论】:

  • 一个是未定义的行为,另一个不是。

标签: c++ type-conversion static-cast


【解决方案1】:

第一个只是转换值:int b = x;int b = static_cast&lt;int&gt;(x); 相同。

第二种情况假设有一个int 住在实际上x 居住的地方,然后尝试读取int。这是完全未定义的行为。 (例如,int 可能比char 占用更多空间,或者char 可能居住在没有int 可以居住的地址。)

【讨论】:

    【解决方案2】:

    第 2 种情况是 C 风格转换(由 bhuang3 标识),但它不是与第 1 种情况等效的 C 风格。那就是 b = (int)x;。情况 2 的 C++ 等价物将是 b = *reinterpret_cast&lt;int*&gt;(&amp;x); 无论哪种方式,情况 2 都是未定义的行为,因为 x 占用一个字节,而在 x 的地址强制读取 int 的数据值会导致分段错误(总线某些系统上的错误)如果它不是int 的合法地址,或者它只会读取接下来的 3 个字节,我们不知道它们的值是什么。因此,如您所见,它显示为“垃圾”。

    【讨论】:

    • @phonetagger.....Case-2 可以方便地查找机器的字节顺序......
    • @noleptr - 是的,有点。但反过来:在 int 位置读取一个字节。如上所述,如果在一个字节位置读取一个 int,如果它没有在一个 int 边界上对齐,它可能会 SEGV。
    • @noleptr:是的;但仅当您使用至少与整数一样长的 char 数组时(否则代码被破坏)。但是这些信息并不是那么有用,任何需要你知道这个(字节顺序)的问题都已经以更好的方式解决了。
    • @LokiAstari - 你确定“更好的方法”没有在其核心使用这样的技巧吗?
    • @phonetagger:可能是这样。但是这个技巧已经在一个功能良好的库中为你抽象出来了。或者它是构建环境中内置的东西,因此已知是正确的并且没有运行时成本。
    【解决方案3】:
    1. static_cast 不提供运行时检查,如果您知道自己引用了特定类型的对象,则会使用它。

    2. 第二个案例其实是c-style cast

    【讨论】:

      猜你喜欢
      • 2019-06-22
      • 2019-09-21
      • 2018-12-07
      • 1970-01-01
      • 1970-01-01
      • 2013-06-28
      • 2011-06-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多