-2
 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;

When I try to run this code there is segmentation fault at line

uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);

In fact, at one place this is running ok. At another place it is giving seg fault.

effeffe
  • 2,821
  • 3
  • 21
  • 44
RAM JI GUPTA
  • 47
  • 1
  • 6
  • Please tell which compiler (and version) are you using, and for which target system. Also give the compilation flags. – Basile Starynkevitch Jan 05 '13 at 13:42
  • 2
    Did you try to isolate this snippet and see what happens? I put this exact code in a simple main function and there is no segfault. – coelhudo Jan 05 '13 at 13:47
  • I guess the explicit conversions to `uint32` in `uint32_t rgb = ((uint32_t)r << 16 | (uint32_t)g << 8 | (uint32_t)b);` are not needed, because you declare `r`, `g`, and `b` to be `uint32`. Is there a place where they are needed, because those variables have a different type? – Andy Prowl Jan 05 '13 at 13:53

1 Answers1

2

Please try to compile your code with all warnings and debug info (e.g. with g++ -Wall -g on Linux) and to improve it till no warnings are given. Learn to use the debugger (i.e. gdb on Linux)

I would guess that the fault is probably at

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

because this may trigger a fault if rgb (i.e. uint32_t) and float don't have the same alignment or size constraints. Some systems (processors, ABIs, compilers) may have different & incompatible constraints for them.


BTW, your code works well with GCC 4.7 on Debian/GNU/Linux/x86-64 invoked as

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

when I have

 #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;
 }  

No warnings, no crashes at execution.

Notice that <cstdint> requires a C++11 conforming compiler.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547