go: proposal: Go 2: make int type panic on overflow

Proposal: change the type int to panic on overflow.

The type int does not have a defined size. That means that people do not expect a particular overflow behavior. It is also the default type of integer constants, and the result type of len, cap and copy, and the key type of range on a slice, array, or string, so it appears frequently in Go programs.

Catching integer overflow will catch many cases where a program behaves incorrectly. Overflow in int values is unexpected but does sometimes occur. When it does occur, it is normally a bug in the program. Panicking rather than wrapping will help Go programmers find these bugs.

This idea arose in the consideration of adding checked integer types, which panic rather than wrap on overflow. A problem with adding new checked integer types is that, as noted above, int is the implied type for several operations. New types would require explicit conversions from int to the new type. It’s unlikely that people would use them, so code would not become safe.

This proposal does not preclude adding more checked integer types in the future, as suggested in #30209 and #30613. It only addresses the handling of the special type int itself.

This would be a change in current program behavior, but since the type does not have a defined size, a program that relies on the wrapping behavior of int is likely to be subtly buggy when run on systems with different sizes of int.

This proposal is a simpler path forward compared to #19623, #19624, #30209, #30613.

A disadvantage of changing only int would be that people might assume that all integer types panic on overflow. Unfortunately, changing the behavior of the other integer types seems much more likely to break existing programs.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 16
  • Comments: 23 (20 by maintainers)

Most upvoted comments

coming from a C background, where int has always been undefined-on-overflow, and most users are still surprised by it: i think i like this idea, but find it slightly-surprising for it to apply to int, but not to int32 or int64. i’d be concerned about impact on existing code, but also i think it would indeed make code safer and mostly catch actual errors.

I vote against this functionality. Motivation

  • other programming languages don’t have it (some even requiring inline assembler to detect the overflow CPU flag being raised)
  • the performance impact is not neglectable.
  • functionality might not be easy to add consistently cross-platform

Although I do see the reason why this is asked. The reasons why GOlang should not do it is the same as all the other languages earlier reached the same conclusion (not to support it).

It’s an interesting idea, but from a language perspective it means that integer overflow is no longer clearly specified. That might be OK but it seems awkward.

A counter-argument to this proposal is that it introduces a panic path to code that currently doesn’t have one. That raises the possibility of unexpectedly crashing a long-running server on an unlikely and untested path. In some cases that can lead to a denial of service attack via a query of death. That is, this proposal can change code that is silently incorrect into code that loudly crashes. While that is often a good tradeoff, sometimes it is not.

I do not have any stats on the frequency of integer wrapping errors. Good question. Not sure how to get those stats.

On x86 the performance impact is an extra instruction, a correctly predicted branch, after most arithmetic operations. I doubt the performance impact would be significant, but we will have to see.

I do not think there should be a build flag for this, any more than there is for other language features.

The uint and uintptr types are both unsigned. For unsigned types wrapping is generally considered less surprising.

The purpose of this proposal is to make most programs avoid overflow without requiring extra work. Adding a new type would defeat that goal. If people are worried about overflow, then they will write code that does not overflow, regardless of whether we add a new type or not. The point is to help people who are not worried about overflow, but should be.