[BUG] `Int` division by zero is silently undefined: returns garbage, returns 0, or crashes with an unsymbolicated stack trace
Nobody has claimed this yet.
- Dominant language
- Mojo
- Stars
- 29.8k
- Forks
- 3.2k
- PR merge metrics
- No merged PRs in 30d
Description
Bug description
Actual behavior
Dividing an Int by zero has no defined behaviour. Depending on how the
denominator reaches the division, the same operation either returns a
nondeterministic value, returns 0, or crashes the process with a raw stack
dump. Nothing in the operators documentation
mentions division by zero, so there is no way to know this without testing for it.
Expected behavior
Python — whose syntax and semantics Mojo otherwise follows closely — raises
ZeroDivisionError here. Code ported from Python silently produces wrong
results instead of failing.
So either:
- Python parity — raise
ZeroDivisionError, or - if the branch is considered too expensive for hot paths: document it as
undefined behaviour in the operators manual, and trap it in debug builds
(as Rust does), so it fails loudly during development rather than corrupting
data silently.
The current state is the worst of both: undocumented, inconsistent between
operators, and inconsistent between runs of the same program.
Steps to reproduce
A. Hard crash
def divide(numerator: Int, denominator: Int) -> Int:
return numerator / denominator
def main():
var values = [7, 0, 3]
for v in values:
print(v, "->", divide(100, v))
Output (identical across 3 runs):
7 -> 14 #0 0x000076c2505bef8e (.../libKGENCompilerRTShared.so+0xfbf8e)
#1 0x000076c2505bc0a6 (.../libKGENCompilerRTShared.so+0xf90a6)
#2 0x000076c2505bfdd0 (.../libKGENCompilerRTShared.so+0xfcdd0)
#3 0x000076c253645330 (/lib/x86_64-linux-gnu/libc.so.6+0x45330)
#4 0x000076c21c0011a7
mojo: error: execution crashed
The message never mentions division by zero.
B. Silent nondeterministic value
def divide(numerator: Int, denominator: Int) -> Int:
return numerator / denominator
def main():
var segments = 7
var duration = 5
var steps = duration / segments # == 0
print("computed denominator:", divide(3, steps))
var zero = 0
print("constant denominator:", divide(3, zero))
Three consecutive runs:
computed denominator: 0 constant denominator: 140736790674968
computed denominator: 0 constant denominator: 140726301657880
computed denominator: 0 constant denominator: 140736819750648
The second value changes on every run and looks like a stack address. Which of
the two operands produces garbage versus 0 is not stable either — in a
slightly different arrangement of the same code the roles were reversed.
C. // and %
With the same list-based shape that crashes for /, both // and % instead
return 0 silently:
def main():
var values = [0]
for v in values:
print("floordiv:", 100 // v) # 0
print("mod:", 100 % v) # 0
System information
System
Pixi version: 0.76.0
TLS backend: rustls
Platform: linux-64
Virtual packages: __unix=0=0
: __linux=6.8.0=0
: __glibc=2.39=0
: __archspec=1=skylake
Cache dir: /home/stefan/.cache/rattler/cache
Auth storage: /home/stefan/.rattler/credentials.json
Config locations: No config files found
Global
Bin dir: /home/stefan/.pixi/bin
Environment dir: /home/stefan/.pixi/envs
Manifest dir: /home/stefan/.pixi/manifests/pixi-global.toml
As I am using uv:
uv pip list
Package Version
click 8.4.2
mblack 26.5.0
mojo 1.0.0
mojo-compiler 1.0.0
mojo-compiler-mojo-libs 1.0.0
mojo-lldb-libs 1.0.0
mypy-extensions 1.1.0
pathspec 1.1.1
platformdirs 4.11.2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Run the three reproductions for /, //, and % to confirm the inconsistent zero-denominator behavior, then read the operators documentation linked in the issue. The work is complete when the project has an agreed zero-division behavior, applies it consistently across these operators, and documents the resulting behavior or failure mode.
Written by the indexing model from the issue text.
Assessment
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 38/100