From 265185e654eded3cfac2b066c0419a425a99fabc Mon Sep 17 00:00:00 2001 From: Niels Lohmann Date: Thu, 8 Oct 2026 16:21:45 +0200 Subject: [PATCH] Fix MSVC C4127 and Infer finding in the view serializer Test the template options through enabled() so that conditions combined with them are not constant, and mark the nav::value() null dereference as a false positive like materialize.hpp does. Signed-off-by: Niels Lohmann --- include/nlohmann/detail/view/serializer.hpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/include/nlohmann/detail/view/serializer.hpp b/include/nlohmann/detail/view/serializer.hpp index 0fb97004e..88ccfbecc 100644 --- a/include/nlohmann/detail/view/serializer.hpp +++ b/include/nlohmann/detail/view/serializer.hpp @@ -397,6 +397,14 @@ class view_serializer std::memcpy(to, from, n); } + /// a compile-time option as a runtime condition: testing the template + /// argument directly makes a condition like `Editable && c` constant when + /// the option is off, which MSVC reports as C4127 + static NLOHMANN_VIEW_ALWAYS_INLINE bool enabled(bool option) noexcept + { + return option; + } + template void dump_compact(const node* root) { @@ -473,6 +481,8 @@ class view_serializer { // write the value at n (read-only documents: and advance n) bool opened = false; + // false positive: n comes from nav::value(), which never returns null for a valid index + // @infer-ignore NULLPTR_DEREFERENCE switch (static_cast(n->kind)) { case value_t::string: @@ -493,14 +503,14 @@ class view_serializer { const std::uint32_t len = number_length(*n); room(len); - if (Editable && (n->flags & node_flags::storage) != 0) + if (enabled(Editable) && (n->flags & node_flags::storage) != 0) { copy_long(w, m_doc.str(*n), len); // a canonical token written by an edit w += len; break; } const char* const token = src + n->off; - if (!SourceNumbers && NLOHMANN_VIEW_UNLIKELY(len == 2 && token[0] == '-' && token[1] == '0')) + if (!enabled(SourceNumbers) && NLOHMANN_VIEW_UNLIKELY(len == 2 && token[0] == '-' && token[1] == '0')) { *w++ = '0'; // parse() reads -0 as the integer 0 } @@ -511,7 +521,7 @@ class view_serializer break; } case value_t::number_float: - if (SourceNumbers && (n->flags & node_flags::storage) != node_flags::edited) + if (enabled(SourceNumbers) && (n->flags & node_flags::storage) != node_flags::edited) { room(n->len); copy(src + n->off, n->len);