strconv: parse_int and parse_uint accept underscores for an explicit base

Closed Beginner friendly
#29,941 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 1 day

A pull request for this has already been merged.

  • #29962 by @medvednikov — merged

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
82/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Domain
backend

Research direction

The bug is in the underscore branch of the shared digit loop in atoi.v (around lines 89-100), which the doc comment at lines 217-218 says should apply only when base is 0. Read that loop first, then check the base-0 tests in atoi_test.v (lines 449-478) and the explicit-base tests (lines 404-447). Done when gating the underscore branch on base == 0 makes parse_int("1_000", 10, 0) return a syntax error, and the existing base-0 tests still pass.

Written by the indexing model from the issue text.

Description

Go permits underscore digit separators only when the base is 0. V accepts them for any base.

// V 0.5.2 5bd6709
parse_int("1_000", 10, 0)   = 1000
parse_int("1_000", 10, 64)  = 1000
parse_uint("1_000", 10, 0)  = 1000
parse_int("ff_ff", 16, 0)   = 65535
parse_int("0x1_0", 0, 0)    = 16      // base 0: both agree, this is correct

// Go 1.26.1
ParseInt("1_000", 10, 0)  -> invalid syntax
ParseInt("1_000", 10, 64) -> invalid syntax
ParseUint("1_000", 10, 0) -> invalid syntax
ParseInt("ff_ff", 16, 0)  -> invalid syntax
ParseInt("0x1_0", 0, 0)   -> 16, nil

The parse_int doc comment (atoi.v:217-218) already states the Go rule: "for argument base 0 only, underscore characters are permitted". The base-0 case works and is tested — atoi_test.v:449-478 pins '0_10' == 8 and '07_7' == 63 — but the underscore branch at atoi.v:89-100 sits inside the shared digit loop and is not gated on the base, so an explicit base gets the separator the doc says it should not have.

atoi_test.v:404-447 looks like it pins the behaviour for all bases, but line 443 calls common_parse_uint(query[0], 0, 32, ...) — base 0 — so it does not cover this.

Gating the branch on base == 0 sends 1_000 down the existing non-digit path, which already produces the right error: parse_int("1 000", 10, 0) returns a syntax error today through that same mechanism.

Measured on V 0.5.2 5bd6709 (tree 5bd67093f9), Go 1.26.1, Windows 11 x64. No patch attached.

Dominant language
V
Stars
38.1k
Forks
2.3k
Avg merge
15h 8m
Merged PRs (30d)
839

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from vlang/v

All issues in vlang/v

Similar issues

More Backend & API Design issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.