Skip to content

Fix build with Apple libc++ lacking floating-point std::from_chars#1160

Closed
daeho-ro wants to merge 3 commits into
BehaviorTree:masterfrom
daeho-ro:fix/apple-libcxx-from-chars-float
Closed

Fix build with Apple libc++ lacking floating-point std::from_chars#1160
daeho-ro wants to merge 3 commits into
BehaviorTree:masterfrom
daeho-ro:fix/apple-libcxx-from-chars-float

Conversation

@daeho-ro

@daeho-ro daeho-ro commented Jul 7, 2026

Copy link
Copy Markdown

Apple's libc++ deletes floating-point std::from_chars (and undefines
__cpp_lib_to_chars), so the unguarded double parse in xml_parsing.cpp
fails to compile on macOS.

Guard it like the other numeric conversions and fall back to std::stod,
keeping the strict full-string validation. Backward-compatible; compile-only
fix (no unit test).

daeho-ro and others added 2 commits July 7, 2026 21:04
The double branch of the XML attribute parser called std::from_chars
unconditionally. Apple's libc++ ships integer from_chars but deletes the
floating-point overload (and undefines __cpp_lib_to_chars), so this fails
to compile on macOS.

Guard it like the other numeric conversions and fall back to std::stod
under the "C" locale, keeping the strict full-string validation.
@facontidavide

Copy link
Copy Markdown
Collaborator

Thanks for this — the Apple libc++ breakage is real and the fix is correctly scoped (only the floating-point from_chars branch is guarded; the integer branch stays as-is, which is right since Apple ships integer from_chars).

One thing I'd like to sort out before merging, plus a smaller note.

1. The stod fallback isn't behaviorally equivalent to from_chars — it accepts a superset.

std::from_chars (general float format) deliberately does not skip leading whitespace, does not accept a leading +, and does not parse hex floats. std::stod accepts all three. The consequence is that the parsed type of a const attribute becomes platform-dependent:

  • value="+1.5" or value=" 1.5" → stored as a std::string on Linux/Windows (from_chars fails, falls through to the string branch), but as a double on macOS (stod succeeds, dbl_pos == size).

That means the same XML can make a Script expression / numeric port work on one platform and hit a type-mismatch on the other. A compile-fix shouldn't change runtime semantics on the affected platform, so I'd like the fallback to reject the same inputs from_chars rejects. A leading-+ / leading-whitespace / 0x guard before the stod call is enough.

2. setlocale(LC_NUMERIC, ...) mutates process-global state (lower priority).

The save/set/restore is correct for this thread, but setlocale affects the whole process. If another thread does any locale-sensitive formatting/parsing while a tree is being parsed, it transiently sees the "C" locale, and concurrent setlocale/locale reads are a data race — the kind of thing our TSan setup is meant to catch. Not a blocker (single-threaded loading is fine), but worth avoiding if the parse can be made locale-independent.

A fully manual .-based parse would close both points at once (no global locale mutation, exact from_chars semantics). If that's more than you want to take on, the minimal path is: keep the setlocale bracket but add the input guard from point 1 — that closes the correctness divergence in a few lines and keeps the PR small.

Either way, would you mind adding a short comment noting the fallback intentionally mirrors from_chars's strict format? Happy to help if you'd like a hand with the guard.

@facontidavide

Copy link
Copy Markdown
Collaborator

I will apply the fixes here: #1167

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants