# Prevent using integer initializers that can generate runtime errors

**URL:** <https://forums.swift.org/t/prevent-using-integer-initializers-that-can-generate-runtime-errors/75467>\
**Category:** Using Swift\
**Created:** [October 18, 2024, 9:15pm UTC](https://forums.swift.org/t/prevent-using-integer-initializers-that-can-generate-runtime-errors/75467 "2024-10-18T21:15:50Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![kainjow](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kainjow/32/32380_2.png) [@kainjow](https://forums.swift.org/u/kainjow)\
**Post date:** [October 18, 2024, 9:15pm UTC](https://forums.swift.org/t/prevent-using-integer-initializers-that-can-generate-runtime-errors/75467/1 "2024-10-18T21:15:51Z")

</div>

It is very easy to use the integer extensions that initialize a type with another that cannot always be represented, but then not fully understand that these initializers aren't always "safe", and that when they fail they generate a runtime error, crashing the process.

For example:

```swift
let a = Int32(-1)
let b = UInt32(a) // "Fatal error: Negative value is not representable"

```

And:

```swift
let a = UInt64(0xFF00000000000000)
let b = UInt32(a) // "Fatal error: Not enough bits to represent the passed value"

```

Is there a way to prevent using these initializers at compile time? The sources show these are preconditions and from what I found only -0unchecked disables these, but this sounds like it disables other good things that generally shouldn't be turned off.

Unfortunately I don't think a linter can help since the types need to be fully understood, as these initializers can also be used with imported C types as aliases.

One idea I imagine could be to annotate these functions and provide a compiler flag to prevent using them.

---

<div class="post-metadata">

**Author:** ![ibex](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ibex/32/30439_2.png) [@ibex](https://forums.swift.org/u/ibex)\
**Post date:** [October 18, 2024, 10:40pm UTC](https://forums.swift.org/t/prevent-using-integer-initializers-that-can-generate-runtime-errors/75467/2 "2024-10-18T22:40:13Z")

</div>

This is one of those things that look easy to do during compilation, but it is not.

```swift
func f () -> UInt64 {
    UInt64(7)
}

func g () -> UInt64 {
    h ()
}

func h () -> UInt64 {
    UInt64(0xFF00000000000000)
}

let u = f ()
let v = UInt32(u) // Ok
        
let u = g ()
let v = UInt32(u) // Fatal error: Not enough bits to represent the passed value

```

Even if the compiler can see the definition of all those functions, solving this problem may still prove hard.

---

<div class="post-metadata">

**Author:** ![kainjow](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kainjow/32/32380_2.png) [@kainjow](https://forums.swift.org/u/kainjow)\
**Post date:** [December 15, 2024, 5:31am UTC](https://forums.swift.org/t/prevent-using-integer-initializers-that-can-generate-runtime-errors/75467/3 "2024-12-15T05:31:29Z")

</div>

I was thinking along the lines of how Rust does it, where (as far as I know) there is no safe way to convert a i32 to u32, but it has [try\_from](https://doc.rust-lang.org/std/primitive.u32.html#method.try_from-9) which can fail, yet for u32 -\> u64 they have [from](https://doc.rust-lang.org/std/primitive.u64.html#method.from-3) which cannot. There is no need to have special knowledge that a function could fail at runtime, unlike Swift, which has a combination of these functions. It seems like it could be a good fit alongside the [strict memory safety proposal](https://forums.swift.org/t/prospective-vision-optional-strict-memory-safety-for-swift/75090) potentially.
