【问题标题】:reinterpret_cast in C++C++ 中的 reinterpret_cast
【发布时间】:2013-01-05 13:37:25
【问题描述】:
 uint32_t r,g,b;
 r = (uint32_t)145;
 g = (uint32_t)131;
 b = (uint32_t)139;
 uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
 float rgbf = *reinterpret_cast<float*>(&rgb);

 uint32_t rgbnew = *(reinterpret_cast<uint32_t *>(&rgbf));
 uint8_t rnew = (rgbnew >> 16) & 0x0000ff;
 uint8_t gnew = (rgbnew >> 8) & 0x0000ff;
 uint8_t bnew = (rgbnew) & 0x0000ff;

当我尝试运行此代码时,行出现分段错误

uint32_t rgb = ((uint32_t)r

事实上,在某个地方运行良好。在另一个地方它给出了段错误。

【问题讨论】:

  • 请告知您使用的是哪个编译器(和版本),以及针对哪个目标系统。还要给出编译标志。
  • 您是否尝试隔离此 sn-p 并查看会发生什么?我把这个确切的代码放在一个简单的 main 函数中,没有段错误。
  • 我想在uint32_t rgb = ((uint32_t)r &lt;&lt; 16 | (uint32_t)g &lt;&lt; 8 | (uint32_t)b); 中对uint32 的显式转换是不需要的,因为您将rgb 声明为uint32。是否有需要它们的地方,因为这些变量具有不同的类型?

标签: c++ pointers pointer-conversion


【解决方案1】:

请尝试使用所有警告和调试信息编译您的代码(例如,在 Linux 上使用 g++ -Wall -g)并对其进行改进,直到没有给出警告为止。学习使用调试器(即 Linux 上的gdb

我猜应该是问题出在

 float rgbf = *reinterpret_cast<float*>(&rgb);

因为如果rgb(即uint32_t)和float 没有相同的对齐或大小约束,这可能会触发错误。某些系统(处理器、ABI、编译器)可能对它们有不同且不兼容的约束。


顺便说一句,您的代码在 Debian/GNU/Linux/x86-64 上的 GCC 4.7 上运行良好,调用为

   g++-4.7 -std=c++11 -Wall -g ramji.cc -o ramji

当我有

 #include <cstdint>
 #include <iostream>

 int main(int argc, char**argv)
 {
   uint32_t r,g,b;
   r = (uint32_t)145;
   g = (uint32_t)131;
   b = (uint32_t)139;
   std::cout << "r=" << r << " g=" << g << " b=" << b << std::endl;
   uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);
   std::cout << "rgb=" << rgb << std::endl;
   float rgbf = *reinterpret_cast<float*>(&rgb);
   std::cout << "rgbf=" << rgbf << std::endl;
   uint32_t rgbnew = *(reinterpret_cast<uint32_t *>(&rgbf));
   std::cout << "rgbnew=" << rgb << std::endl;
   uint8_t rnew = (rgbnew >> 16) & 0x0000ff;
   uint8_t gnew = (rgbnew >> 8) & 0x0000ff;
   uint8_t bnew = (rgbnew) & 0x0000ff;
   std::cout << "rnew=" << rnew << " gnew=" << gnew 
        << " bnew=" << bnew << std::endl;
   return 0;
 }  

没有警告,执行时没有崩溃。

请注意,&lt;cstdint&gt; 需要符合 C++11 的编译器。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-06-17
    • 2011-06-10
    • 2013-10-30
    • 1970-01-01
    • 2011-06-10
    • 1970-01-01
    相关资源
    最近更新 更多