Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Is there a best way to deal with undefined behavior in bitwise conversion between floats and integers in C++14, C++17, C++20 and different compilers?

Which way in below tests is the most preferred in terms of dealing with undefined behavior, auto-vectorization (for struct of arrays) and portability (clang,gcc,msvc,icc)?

Is there another way of doing same operation?

#include <iostream>
#include <cstring>

union trick1
{
  float fvar;
  int ivar;
};

struct trick2
{
  float fvar;
  int ivar()
  {
      int result;
      std::memcpy(&result,&fvar,sizeof(float));
      return result;
  }
};

struct trick3
{
    float fvar;
    int ivar()
    {
        int result=0;
        asm ("mov %0,%0"
         : "=r" (result)
         : "0" (fvar));
        return result;
    }
     
};

struct trick4
{
    float fvar;
    int ivar()
    {
        int result;
        result = *reinterpret_cast<int*>(&fvar);
        return result;
    }
};

int main()
{
    trick1 test1;
    test1.fvar = 3.14f;
    // 1078523331
    std::cout<<test1.ivar<<std::endl;

    trick2 test2;
    test2.fvar = 3.14f;
    // 1078523331
    std::cout<<test2.ivar()<<std::endl;
    
    trick3 test3;
    test3.fvar = 3.14f;
    // 1078523331
    std::cout<<test3.ivar()<<std::endl;  
    
    trick4 test4;
    test4.fvar = 3.14f;
    // 1078523331
    std::cout<<test4.ivar()<<std::endl;  
    return 0;
}

For example, is memcpy ok for converting array of floats to array of integers bitwise?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

trick1: Undefined behaviour.

trick2: Well defined with the precondition that sizeof(int) == sizeof(float), but not as simple as std::bit_cast

trick3: Non-standard; not portable.

trick4: Undefined behaviour.

I recommend std::bit_cast when applicable:

return std::bit_cast<int>(fvar);
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading