Earlier quoted context omitted.
There is absolutely no special treatment afforded to the GSL by any of the target platforms. While we can't inspect MSVC's source code, both clang and GCC do not have any support or affordance for the GSL whatsoever and it would be very unusual to expect MSVC's source code to have some kind of affordance for this library.
The 'special treatment' isn't technical, it's procedural -- insofar as if, during development for a new release, MSVC were to land some changes that broke GSL, Microsoft's testing would catch that and ensure that the changes were reverted or fixed to support the latter, prior to shipping. Since they're built as part of the same operating system, they can make sure not to step on one another's toes -- which is not a g…
C++ float-to-int conversion can be undefined behavior
31–40 of 70 posts
Re: C++ float-to-int conversion can be undefined behavior
#32Earlier quoted context omitted.
Architecture dependent is not the same as undefined.
Also, the spec says it’s undefined. But compiler authors can always special-case their own compilers.
Re: C++ float-to-int conversion can be undefined behavior
#33Earlier quoted context omitted.
Undefined behavior is not the same as implementation-defined or unspecified behavior. A program with undefined behavior is by definition an incorrect program. But there are cases where the spec actually gives some margin to the implementation. Programs relying on the choices of the implementation may be correct, even if non-portable.
>A program with undefined behavior is by definition an incorrect program. This is simply false and an oft repeated myth. Undefined behavior has a specific technical definition that is in the C++ standard [1] and there is absolutely no mention in that definition or the implication of that definition that undefined behavior necessarily results in an invalid or incorrect program. The definition of undefined behavior, ri…
That's saying that programs that exhibit undefined behaviour are not governed by the C++ spec. For a program to be a valid, spec governed piece of C++ code it has to exhibit no undefined behaviour (outside of some constraints). Its accurate to say that any undefined behaviour results in the code being executed no longer being C++, and it can have any behaviour. That's synonymous in common developer speak with 'incorrect', as its desirable for your C++ code to be executed as C++
Re: C++ float-to-int conversion can be undefined behavior
#34This will do wonders for speed. Actually explicitly using the safe isntr might be better. Something like this will happily compile to a single instr and cause you no grief even if the compiler had it out for you with UB. These instrs all clearly define outputs for all inputs (note that said outputs may not match across architectures)
static inline __attribute__((always_inline)) int f2i(float myFloat) {
int myInt;
#if defined(__arm__)
asm("VCVT.S32.F32 %0, %1":"=r"(myInt), "t"(myFloat));
#elif defined (__aarch64__)
asm("FCVTZS %0, %1":"=r"(myInt), "w"(myFloat));
#elif defined (__x86_64__)
asm("CVTTSS2SI %0, %1":"=r"(myInt), "x"(myFloat));
#else
#if 0 // be boring
if (myFloat TOO_BIG_FLOAT)
abort();
#else
#warning "Embrace the UB"
#endif
myInt = (int)myFloat;
#endif
return myInt;
}Re: C++ float-to-int conversion can be undefined behavior
#35Earlier quoted context omitted.
No, UB is allowed special powers for compiler and standard library implementors, which is what Herb Sutter means with internal behaviour. Meaning MSVC is aware of these cases, so the compiler has special cases for it.
Clang is a target for the GSL though. How can MSVC's special powers prevent this from being exploitable UB in Clang/LLVM? This code boils down to static_cast (some_double); so nothing fancy is going on here
However that was me guessing from Herb Sutter's reply.
Re: C++ float-to-int conversion can be undefined behavior
#36Re: C++ float-to-int conversion can be undefined behavior
#37Earlier quoted context omitted.
Undefined behavior is not the same as implementation-defined or unspecified behavior. A program with undefined behavior is by definition an incorrect program. But there are cases where the spec actually gives some margin to the implementation. Programs relying on the choices of the implementation may be correct, even if non-portable.
>A program with undefined behavior is by definition an incorrect program. This is simply false and an oft repeated myth. Undefined behavior has a specific technical definition that is in the C++ standard [1] and there is absolutely no mention in that definition or the implication of that definition that undefined behavior necessarily results in an invalid or incorrect program. The definition of undefined behavior, ri…
Honestly, you'd have a better argument by quoting that "Correct execution" can include undefined behavior and erroneous behavior, depending on the data being processed". Which is quite a wild sentence to read, but here we are.
Re: C++ float-to-int conversion can be undefined behavior
#38Herb Sutter's comment on why it's ok is confusing to me: > Regarding the use of UB internally: It's okay and if anyone is worried about it the use of UB is benign on the platforms we target (e.g., they don't involve hitting any hardware trap representations for these types) Isn't the outcome of the UB (ie. whether it will "rm -rf /" or something else) dependent on both the target and the compiler? And the compiler (o…
For what it's worth, a GSL developer later reopened that GitHub issue and stated that they're going to look into fixing the UB. Sutter may have just been stating an assumption. https://github.com/microsoft/GSL/issues/786#issuecomment-513... > I'll raise this issue in the next internal GSL sync. I'd agree with y'all that this behavior: https://godbolt.org/z/4Tr1fe9xG is undesirable
The problem isn't, "oh no what if my CPU's float->int conversion instruction traps", that's an extremely naive way to think about UB. Everyone who has thought seriously about UB in C++ for any length of time knows this. It's worrying that this was Sutter's response.
Re: C++ float-to-int conversion can be undefined behavior
#39Herb Sutter's comment on why it's ok is confusing to me: > Regarding the use of UB internally: It's okay and if anyone is worried about it the use of UB is benign on the platforms we target (e.g., they don't involve hitting any hardware trap representations for these types) Isn't the outcome of the UB (ie. whether it will "rm -rf /" or something else) dependent on both the target and the compiler? And the compiler (o…
In LLVM, the result of floating-to-int conversion that is out of range of the int is a poison value, which means you get essentially the full unpredictability of UB. That said, I'm a little hard-pressed to think of optimizations that would actually take advantage of poison, because floating-point range isn't really computed in the optimizer.
I don't know exactly which optimization passes do what, but a few observations:
* The 'foo(unsigned int n)' function should never return a value that's greater than 'n', since it returns 'i * The value printed by the 'foo' function should always be the same as the value that's returned.
Yet the value it prints is 2700624104 (which is greater than 'n', which is 10 in this case), and the returned value is 2700623376, which is different. (The exact numbers vary run to run)
If the conversion "just" resulted in a bogus value, we would have expected some number <=10 to be printed two times.
Re: C++ float-to-int conversion can be undefined behavior
#40Earlier quoted context omitted.
UB is bad not because it actually leads to any particular result on any particular platform or compiler, but because semantically it invalidates assumptions about a program. Rust is explicit on this, but it absolutely still applies to C/C++.
Well because it could lead to any result on some platform or compiler, it invalidates assumptions about the program.