2

I am actually working on an old source code that use c-style cast.

In that code, we cast some double values to unsigned long. The cast is correctly done when the code is compiled with VS2017 toolset v141.

But now, we are migrating to VS2019 toolset v142, and the cast failed. It returns 0xffffffff !

Is there a changement in the v142 that affects the cast ? If yes, is there an option or any tricks that i can do to have the correct value ?

For example :

#include <iostream>
#include <limits>

typedef std::numeric_limits< double > dbl;

int main()
{
    double value = -699457.70832337427;
    unsigned long ulValue = (unsigned long)value;
    unsigned long sculValue = static_cast<unsigned long>(value);

    std::cout.precision(dbl::max_digits10);

    std::cout << "Value : " << value << " - C-Style Cast " << ulValue << " - Static Cast " << sculValue << "\n";
    std::cout << "Value : " << value << " - C-Style Cast " << std::hex << ulValue << std::hex << " - Static Cast " << sculValue << "\n";
}

with vs2017 and toolset v141, output is : Value : -699457.70832337427 - C-Style Cast 4294267839 - Static Cast 4294267839 Value : -699457.70832337427 - C-Style Cast fff553bf - Static Cast fff553bf

with vs2019 and toolset v142, output is : Value : -699457.70832337427 - C-Style Cast 4294967295 - Static Cast 4294967295 Value : -699457.70832337427 - C-Style Cast ffffffff - Static Cast ffffffff

The only trick i found for now is casting first the value to long and after to unsigned long but it's not really an ideal solution !

Thanks by advance !

  • 1
    You are casting negative double values to unsigned long? Does it make any sense? – n. m. could be an AI Oct 03 '19 at 09:18
  • 1
    Not able to reproduce this problem. Building with v142 toolset yields the same results as listed for v141 – user7860670 Oct 03 '19 at 09:23
  • 1
    Possible duplicate of [double to unsigned int / char](https://stackoverflow.com/questions/21660250/double-to-unsigned-int-char) – Axalo Oct 03 '19 at 09:24
  • Yes, i know i am casting negative values to unsigned. I don't have all the reasons of this cast but the fact is that's worked before (this kind of code is embedded in many machines) and failed with the new toolset. – RikikiPtitKiwi Oct 03 '19 at 09:26
  • 3
    Ok I see. Code with unknown intent that relies on undefined behaviour runs on many machines, and we are busy with letting it continue to run. I am confident that our future is in good hands. – n. m. could be an AI Oct 03 '19 at 09:44
  • 1
    What kind of machines are we talking about? Asking for a friend. – Timo Oct 03 '19 at 09:53

2 Answers2

1

Floating-integral conversions [conv.fpint]

A prvalue of a floating-point type can be converted to a prvalue of an integer type. The conversion truncates; that is, the fractional part is discarded. The behavior is undefined if the truncated value cannot be represented in the destination type.

Community
  • 1
  • 1
n. m. could be an AI
  • 112,515
  • 14
  • 128
  • 243
0

As has been pointed out, it is undefined behavior to cast a negative floating point value to an unsigned integral type. You say

The only trick i found for now is casting first the value to long and after to unsigned long but it's not really an ideal solution !

Yes, it is a bit cumbersome; but it is the only way to achive well-defined behavior (which is actually implementation-defined behavior in this case).

j6t
  • 9,150
  • 1
  • 15
  • 35