Repository navigation
Construct remaining hot-path exceptions out of line so core functions inline - #5838
Merged
Merged
Conversation
gregmarr
approved these changes
Oct 15, 2026
| */ | ||
| template<typename BasicJsonType> | ||
| JSON_HEDLEY_NO_RETURN inline void throw_type_must_be(const char* expected, const BasicJsonType& j) | ||
| JSON_HEDLEY_NO_RETURN JSON_HEDLEY_NEVER_INLINE inline void throw_type_must_be(const char* expected, const BasicJsonType& j) |
Contributor
There was a problem hiding this comment.
You don't need inline on function templates. (Full specializations are not templates, and so do need it.) That eliminates the initial confusion of ...NEVER_INLINE followed by inline.
nlohmann
added a commit
that referenced
this pull request
Oct 15, 2026
The at() cold-throw work moves to #5838; this PR keeps only the array-to-container from_json speed-up and its benchmark. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Owner
Author
|
Written by Claude Code on behalf of @nlohmann. Changes since the approval, following the decisions on the #5783 overlap (head 971330a):
@gregmarr could you take another look? |
nlohmann
force-pushed
the
perf/out-of-line-throws
branch
from
October 15, 2026 06:24
971330a to
577067d
Compare
nlohmann
added this pull request to stack #5841
October 15, 2026 06:24
nlohmann
force-pushed
the
perf/out-of-line-throws
branch
from
October 15, 2026 08:56
577067d to
b0b7fcd
Compare
nlohmann
force-pushed
the
perf/out-of-line-throws
branch
from
October 15, 2026 09:54
b0b7fcd to
0570c5b
Compare
gregmarr
reviewed
Oct 15, 2026
|
|
||
| /// @brief shared implementation of the const and non-const at() overloads | ||
| /// @throw std::out_of_range if @a key is not found | ||
| JSON_HEDLEY_NO_RETURN JSON_HEDLEY_NEVER_INLINE |
Contributor
There was a problem hiding this comment.
move this before the comment block for at_impl, and optionally add its own comment block.
Owner
Author
There was a problem hiding this comment.
Done in 433d4bb: throw_key_not_found() now sits before at_impl()'s comment block and has its own doc comment.
(Written by Claude Code.)
gregmarr
approved these changes
Oct 15, 2026
nlohmann
force-pushed
the
perf/out-of-line-throws
branch
from
October 15, 2026 17:41
433d4bb to
26bf1a0
Compare
nlohmann
force-pushed
the
perf/out-of-line-throws
branch
from
October 15, 2026 17:43
26bf1a0 to
c4cadd9
Compare
nlohmann
force-pushed
the
perf/out-of-line-throws
branch
from
October 15, 2026 17:45
c4cadd9 to
12a5527
Compare
… inline Signed-off-by: Niels Lohmann <mail@nlohmann.me>
Signed-off-by: Niels Lohmann <mail@nlohmann.me>
nlohmann
force-pushed
the
perf/out-of-line-throws
branch
from
October 15, 2026 17:54
12a5527 to
4569c02
Compare
nlohmann
added a commit
that referenced
this pull request
Oct 15, 2026
These PRs were merged while their CI runs were cancelled, so the warnings went unnoticed. All of them fail the -Werror builds: - json_pointer.hpp (#5836): size_t += int under GCC -Wsign-conversion - binary_reader.hpp (#5839): char_int_type passed as char under GCC -Wconversion - json.hpp (#5838): @throw without a description under clang -Wdocumentation - string_escape.hpp (#5836): escape_into() was inserted between escape() and its documentation, so the @return was attached to a void function - unit-diagnostics.cpp (#5832): clang -Wnrvo in a lambda without an explicit return type - unit-to_json-rvalue.cpp (#5837): GCC -Wnoexcept (C++20) and clang -Wunneeded-member-function on the test type Signed-off-by: Niels Lohmann <mail@nlohmann.me>
nlohmann
added a commit
that referenced
this pull request
Oct 16, 2026
- ci_test_noexceptions: the JSON Patch section of unit-throw_messages and the strict dumps in unit-serialization catch exceptions, which JSON_NOEXCEPTION turns into std::abort(); skip them there. - ci_cppcheck: insert() and iter_impl::key() ended with a call to a noreturn throw helper, which Cppcheck reports as missingReturn; check the error case first and end with the return, like the other functions. - ci_single_binaries: ordered_map.hpp uses the Hedley macros since #5838, so include hedley.hpp (IWYU). - MSVC: also wrap the second vector<json> comparison in unit-constructor2 in parentheses. Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of the inlining-blocker sweep (Clang
-Rpass-missed=inline+ assembly inspection): inline exception construction (concat(...),create(...)) keepsget_ref,operator[](size_type), the iterator operators anderase/insertout of line.Changes
detail::throw_literal<Exc>(id, const char*, ctx)(NO_RETURN+NEVER_INLINE) used by the 19 literal throw sites injson.hpp(json_valuector, constructors,erase×4,insert×10,update) and 8 initer_impl(key(),operator<×2,+=,-,[],==,throw_cannot_get_value).NEVER_INLINEhelpers for the message-building sites:get_ref_impl, non-constoperator[](size_type)length error, iterator-range constructor.at()(taken over from Speed up array-to-container from_json #5833):at(size_type)(const and non-const),erase(size_type)share onethrow_array_index_out_of_range(idx, j)helper; the key-not-found throw ofat(key)(jsonandordered_json) usesthrow_key_not_found(key, j).iter_impl::throw_cannot_get_value()(from Use and extend the detail helpers to remove duplicated code #5783) is itself markedNEVER_INLINEinstead of wrapping it.NEVER_INLINEadded tothrow_type_must_be/throw_cannot_use_with;ordered_map::at_implthrows via a helper.unit-throw_messages.cpppins id andwhat()text of the moved sites (includingat(idx)const/non-const,at(key)forjson/ordered_json,erase(idx)) (passes identically on the old and new headers). Exception types, ids and messages are unchanged.Numbers (Apple clang 21, -O2)
get_ref<const string&>arr[i]+=-[]<erase(it)+push_backinsert+erasestd::sortof 10k intsat(i)in-range, const + non-const mixGCC 16:
erase/insert−20–35 %, caller frames shrink (get_ref192→16 B), otherwise neutral. Parsing unchanged. Code size −2–3 % at -O2; -Os is within noise (+0.5 % on the bench binary).JSON_NOEXCEPTIONandJSON_THROW_USERbuilds compile.Coordination
This PR now owns every out-of-line throw, so #5833 shrinks to
from_json. Expect textual conflicts with #5835 (iter_implarray fast path,throw_compare_different_values); I will rebase after it merges.Breaking changes
None. No public API changes; exception types, ids and messages are byte-identical to
develop. Only private/detailhelpers were added.🤖 Generated with Claude Code