Rustc only warns when a value is assigned that overflows

I find that, in my opinion, very strange behavior. Rustc panics when a variable overflows at run time; it makes sense to me. However, it only triggers a warning when a value that overflows is assigned at compile time. Isn't that a compile-time error? Otherwise, the two behaviors seem inconsistent.

I expect a compile-time error:

fn main() { let b: i32 = 3_000_000_000; println!("{}", b); } 

Produces:

 <anon>:2:18: 2:31 warning: literal out of range for i32, #[warn(overflowing_literals)] on by default <anon>:2 let b: i32 = 3_000_000_000; 

Playground 1

This makes sense to me:

 fn main() { let b: i32 = 30_000; let c: i32 = 100_000; let d = b * c; println!("{}", d); } 

It produces:

 thread '<main>' panicked at 'arithmetic operation overflowed', <anon>:4 playpen: application terminated with error code 101 

Playground 2

Edit:

Given a comment by FrancisGagné, and I found that Rust implements statements that check overflow during an operation, such as checked_mul , I see that overflow checks need to be performed. This makes sense because the release version must be optimized, and constantly checking for overflows can become expensive. Therefore, I no longer see "inconsistency." However, I am still surprised that assigning a value that overflows will not lead to a compile-time error. In golang it will be: Go to the playground

+5
source share
1 answer

Actually, your comments do not match the behavior you observe:

  • in your first example: you get a compilation warning that you ignore, and thus the compiler outputs that you want the transfer behavior.
  • in your second example: you get a runtime error

The Go example is similar to the first Rust example (except that Go, by design, has no warnings).


In Rust, underflow, or overflow, an unspecified value is obtained, which can be ! or lower in computer science, a special value indicating that the control flow diverges, which generally means either abortion or an exception.

This specification allows you to:

  • applying debug mode to catch all overflows the moment they happen.
  • 1 release mode is not used (and wrapping arithmetic is used there)

and nevertheless, both modes are compatible with the specification.

1 Without using the default, you can, if you choose for relatively modest performance, outside of the heavy numeric code, activate the overflow check in Release with a simple flag.


About the cost of overflow checks: the current situation with Rust / LLVM is useful for debugging, but is not really optimized. Thus, in this framework, the cost of overflow is worth it. If the situation improves, then rustc can decide, one fine day, to activate the default overflow check even in Release.

In Midori (a Microsoft experimental OS developed in a language similar to C #), overflow checking was enabled even in Release versions:

In Midori, we compiled with the default overflow check. This is different from C # stock, where you must explicitly pass the / checked flag for this behavior. In our experience, the amount of unexpected overflows that were caught and unintentionally was worth the inconvenience and expense. But this meant that our compiler needed to understand very well how to eliminate unnecessary ones.

Apparently, they improved their compiler to:

  • he will talk about ranges of variables and statically eliminate boundary checks and overflow checks whenever possible.
  • it will aggregate checks as much as possible (one check for several potentially overflowing operations)

The latter should only be executed in Release (you lose accuracy), but it reduces the number of branches.

So what is the cost?

Potentially different arithmetic rules that interfere with optimization:

  • in regular arithmetic, 64 + x - 128 can be optimized to x - 64 ; with overflow checks, the compiler may not be able to perform this optimization.
  • vectorization may also be difficult if the compiler does not have built-in overflow checking tools.
  • ...

However, if the code is not very numerical (for example, scientific modeling or graphics), this can affect it.

+3
source

Source: https://habr.com/ru/post/1242216/


All Articles