[libcxx-commits] [libcxx] [libc++] Optimize num_get integral functions (PR #121795)

Masaki Moriguchi via libcxx-commits libcxx-commits at lists.llvm.org
Sat Nov 1 06:06:34 PDT 2025


morinmorin wrote:

@philnik777 Thank you for the comment. Here's the rationale behind the two test cases.

Stage 3 converts the accumulated sequence using the rules of `strtoll`. With base = 0, `strtoll` specifies that (emphasis mine)
> the expected form of the subject sequence is that of **an integer constant** as described in 6.4.5.2

This is 7.24.2.8 p3 in WG14 N3299 (C23 draft). In this context, "integer constant" corresponds to a C++ integer literal.

**C integer constants**
6.4.5.2 p1 in N3299 specifies the literal `0` as an octal integer constant. Additionally, 6.4.5.2 p4 says:
> An octal constant consists of the prefix 0 optionally followed by a sequence of the digits 0 through 7 only

This should be understood as "the **digit** 0 optionally followed by a sequence of the digits 0 through 7 only", which matches the formal grammar. The C++ rules for integer literals are analogous.

**The first test case**
> When basefield is 0, a standard-conforming implementation parses "0" as (octal) zero, does not set failbit, and consumes all characters.

- Stage 2 yields "0".
- Stage 3 converts "0" to `0`.
- Because Stage 3 successfully converts the entire output of Stage 2, `failbit` is not set.

**The second test case**
> When basefield is 0, a standard-conforming implementation parses "08" as (octal) zero, does not set failbit, and consumes only the leading "0".

- Under the rules of `scanf("%i",…)`/`strtol(…,…,0)`, "08" is not a valid sequence. So Stage 2 does not accumulate '8'. It yields "0" and the trailing '8' remains unconsumed for subsequence extraction.
- Stage 3 converts "0" to `0`.
- Again, because Stage 3 successfully converts the entire output of Stage 2, `failbit` is not set.

https://github.com/llvm/llvm-project/pull/121795


More information about the libcxx-commits mailing list