digitalmars.D - Spec on casting to integer with smaller range than value
- Johan (12/12) Mar 28 2020 Hi all,
- Stefan Koch (2/14) Mar 28 2020 cast (ubyte)x is the same as = ((cast(uint)x) & 0xff)
- Johan (3/4) Mar 28 2020 Where does the spec say that?
- user1234 (4/11) Mar 28 2020 is the trunc() that happens when casting a FP to integral type.
- Patrick Schluter (2/6) Mar 29 2020 It's a consequence of the int promotion rule D adheres to.
- kinke (8/11) Mar 28 2020 The 2nd cast, float to int, should be
- Dennis (4/6) Mar 28 2020 Which would make `cast(int) someFloat` not allowed in @safe code.
- kinke (3/8) Mar 28 2020 @safe is about memory corruption, not about disallowing any
- Dennis (8/17) Mar 28 2020 https://dlang.org/spec/function.html#function-safety
- Dennis (4/8) Mar 28 2020 This came up before in different discussions:
- kinke (9/13) Mar 28 2020 In LLVM lingo, the out-of-bounds cast wouldn't be undefined
- Timon Gehr (2/4) Mar 29 2020 It can't be full-blown UB as such a cast works in @safe code.
Hi all, Where can I read in the spec what the outcomes of the following are? ``` uint a = 260; auto b = cast(ubyte) a; float f = 1.203125f * 255.0f; auto zz = cast(ubyte) f; // https://github.com/ldc-developers/ldc/issues/3237 ``` Thanks, Johan
Mar 28 2020
On Saturday, 28 March 2020 at 12:09:49 UTC, Johan wrote:Hi all, Where can I read in the spec what the outcomes of the following are? ``` uint a = 260; auto b = cast(ubyte) a; float f = 1.203125f * 255.0f; auto zz = cast(ubyte) f; // https://github.com/ldc-developers/ldc/issues/3237 ``` Thanks, Johancast (ubyte)x is the same as = ((cast(uint)x) & 0xff)
Mar 28 2020
On Saturday, 28 March 2020 at 15:23:19 UTC, Stefan Koch wrote:cast (ubyte)x is the same as = ((cast(uint)x) & 0xff)Where does the spec say that? -Johan
Mar 28 2020
On Saturday, 28 March 2020 at 19:11:04 UTC, Johan wrote:On Saturday, 28 March 2020 at 15:23:19 UTC, Stefan Koch wrote:cast (ubyte)x is the same as = ((cast(uint)x) & 0xff)Where does the spec say that? -Johancast(uint)xis the trunc() that happens when casting a FP to integral type. https://dlang.org/spec/expression.html#cast_expressions §7.& 0xFFis not specified but is the normal part of the cast uint -> ubyte.
Mar 28 2020
On Saturday, 28 March 2020 at 19:11:04 UTC, Johan wrote:On Saturday, 28 March 2020 at 15:23:19 UTC, Stefan Koch wrote:It's a consequence of the int promotion rule D adheres to.cast (ubyte)x is the same as = ((cast(uint)x) & 0xff)Where does the spec say that?
Mar 29 2020
On Saturday, 28 March 2020 at 12:09:49 UTC, Johan wrote:float f = 1.203125f * 255.0f; auto zz = cast(ubyte) f; // https://github.com/ldc-developers/ldc/issues/3237The 2nd cast, float to int, should be https://dlang.org/spec/expression.html#cast_expressions, §7: 'Casting a floating point value to an integral type is the equivalent of converting to an integer using truncation.' It doesn't specify the behavior if that integer doesn't fit; that should probably be explicitly mentioned as undefined behavior, to account for the observed LLVM/gcc behavior.
Mar 28 2020
On Saturday, 28 March 2020 at 15:33:35 UTC, kinke wrote:that should probably be explicitly mentioned as undefined behavior, to account for the observed LLVM/gcc behavior.Which would make `cast(int) someFloat` not allowed in safe code. Is there any chance LLVM could be instructed to treat it as implementation-defined behavior?
Mar 28 2020
On Saturday, 28 March 2020 at 15:47:04 UTC, Dennis wrote:On Saturday, 28 March 2020 at 15:33:35 UTC, kinke wrote:safe is about memory corruption, not about disallowing any undefined behavior.that should probably be explicitly mentioned as undefined behavior, to account for the observed LLVM/gcc behavior.Which would make `cast(int) someFloat` not allowed in safe code.
Mar 28 2020
On Saturday, 28 March 2020 at 16:06:39 UTC, kinke wrote:safe is about memory corruption, not about disallowing any undefined behavior.The spec provides two definitions:Safe functions are functions that are statically checked to exhibit no possibility of undefined behavior. Undefined behavior is often used as a vector for malicious attacks.https://dlang.org/spec/function.html#function-safetyMemory Safety for a program is defined as it being impossible for the program to corrupt memory. Therefore, the safe subset of D consists only of programming language features that are guaranteed to never result in memory corruption.https://dlang.org/spec/memory-safe-d.html Presence of undefined behavior is sufficient to cause memory corruption, and memory corruption itself is undefined behavior, so the definitions are equivalent and both describe the same thing.
Mar 28 2020
On Saturday, 28 March 2020 at 16:15:08 UTC, Dennis wrote:Presence of undefined behavior is sufficient to cause memory corruption, and memory corruption itself is undefined behavior, so the definitions are equivalent and both describe the same thing.This came up before in different discussions: https://github.com/dlang/dlang.org/pull/2578#discussion_r257200332 https://forum.dlang.org/post/qu53go$r6v$1 digitalmars.com
Mar 28 2020
On Saturday, 28 March 2020 at 15:47:04 UTC, Dennis wrote:Which would make `cast(int) someFloat` not allowed in safe code.In LLVM lingo, the out-of-bounds cast wouldn't be undefined behavior per se, but yield a 'poison' value, whose later usage might eventually trigger undefined behavior, depending on what exactly you're doing with it.Safe functions are functions that are statically checked to exhibit no possibility of undefined behavior.If that's really the ultimate goal, then these casts would probably need a prefixed bounds check in safe code, just like an array bounds check (incl. omitting it if it can be statically determined to fit).
Mar 28 2020
On 28.03.20 16:33, kinke wrote:that should probably be explicitly mentioned as undefined behavior, to account for the observed LLVM/gcc behavior.It can't be full-blown UB as such a cast works in safe code.
Mar 29 2020