Why can't I reinterpret_cast uint to int?

后端 未结 7 1106
借酒劲吻你
借酒劲吻你 2020-12-29 23:40

Here\'s what I want to do:

const int64_t randomIntNumber = reinterpret_cast (randomUintNumber);

Where randomUintNumber is of type

7条回答
  •  我在风中等你
    2020-12-30 00:17

    Reinterpret bit pattern with memcpy, transform type with static cast

    Using reinterpret_cast you are violating strict aliasing. This is bad, as it ends up with undefined behavior (maybe you code malfunctions with a new compiler version.) What is the Strict Aliasing Rule and Why do we care? is a great article, describing the problem and its solution (maybe skip the lengthy part "Now, to the Rule-Book" ;) ). It recommends memcpy and argues, that compiler optimization will skip the copying anyway.

    code

    Interactive code here. In your specific case, all options yield the same result. This changes, when playing with newType and randomUintNumber.

    #include 
    #include 
    
    int main()
    {
        typedef int64_t newType; // try: double, int64_t
        
        uint64_t randomUintNumber = INT64_MAX + 10000; // try: 64000, INT64_MIN, INT64_MAX, UINT64_MAX, INT64_MAX + 10000
        std::cout << "INT64_MIN: " << INT64_MIN << std::endl;
        std::cout << "UINT64_MAX: " << UINT64_MAX << std::endl;
        std::cout << "INT64_MAX: " << INT64_MAX << "\n\n";
        std::cout << "randomUintNumber: " << randomUintNumber << "\n\n";
        
        // const int64_t randomIntNumber = reinterpret_cast (randomUintNumber);
        std::cout << "as \"const int64_t randomIntNumber = reinterpret_cast (randomUintNumber);\" does not work, here are some options ...\n\n";
        
        std::cout << "BAD [undefined behavior!]:" << std::endl;
        const newType a = reinterpret_cast (randomUintNumber);
        std::cout << "\treinterpret_cast (randomUintNumber): " << a << std::endl;
        
        const newType b = reinterpret_cast (randomUintNumber);
        std::cout << "\treinterpret_cast (randomUintNumber): " << b << std::endl;
        
        std::cout << "\nGOOD: " << std::endl;
        const newType c = (int64_t) randomUintNumber;
        std::cout << "\t(int64_t) randomUintNumber [static cast, sometimes reinterprets bit pattern]: " << c << std::endl;
        
        const newType d = static_cast(randomUintNumber);
        std::cout << "\tstatic_cast(randomUintNumber) [the same as before]: " << d << std::endl;
        
        static_assert(sizeof(uint64_t) == sizeof(newType), "should not be taken for granted ...");
        newType eNotConst;
        std::memcpy(&eNotConst, &randomUintNumber, sizeof(uint64_t));
        const newType e = eNotConst;
        std::cout << "\tstd::memcpy(&eNotConst, &randomUintNumber, sizeof(uint64_t)); [definately reinterprets bit pattern]: " << e << std::endl;
        
        
        return 0;
    }
    

    output

    INT64_MIN: -9223372036854775808
    UINT64_MAX: 18446744073709551615
    INT64_MAX: 9223372036854775807
    
    randomUintNumber: 9223372036854785807
    
    as "const int64_t randomIntNumber = reinterpret_cast (randomUintNumber);" does not work, here are some options ...
    
    BAD [undefined behavior!]:
        reinterpret_cast (randomUintNumber): -9223372036854765809
        reinterpret_cast (randomUintNumber): -9223372036854765809
    
    GOOD: 
        (int64_t) randomUintNumber [static cast, sometimes reinterprets bit pattern]: -9223372036854765809
        static_cast(randomUintNumber) [the same as before]: -9223372036854765809
        std::memcpy(&eNotConst, &randomUintNumber, sizeof(uint64_t)); [definately reinterprets bit pattern]: -9223372036854765809
    

提交回复
热议问题