mirror of
https://github.com/nlohmann/json.git
synced 2026-10-22 14:08:13 +00:00
Keep the serializer's buffers out of -Weffc++ and cpplint warnings
GCC's -Weffc++ asks for the three buffers in the member initialization list, which would zero them again. They are now of a type with an empty user-provided constructor (as the json_view builder's frame stack), so they are listed there and stay uninitialized. The 8-to-31-byte branch of the short-string writer no longer spans an #if with a dangling else, which cpplint read as an else body without braces. dump() instructions (Apple clang, twitter/citm/canada, compact and indented) are unchanged within noise (-0.3 % to +0.6 %). Signed-off-by: Niels Lohmann <mail@nlohmann.me>
This commit is contained in:
2 files changed
+54
-58
No files matched your search
@@ -82,17 +82,20 @@ class serializer
|
|||||||
being threaded through every call to @ref dump, @ref dump_internal and
|
being threaded through every call to @ref dump, @ref dump_internal and
|
||||||
@ref dump_iteratively.
|
@ref dump_iteratively.
|
||||||
*/
|
*/
|
||||||
serializer(output_adapter_protocol<char>& s, const char ichar, // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init): the buffers are written before they are read
|
serializer(output_adapter_protocol<char>& s, const char ichar,
|
||||||
const bool pretty_print_ = false,
|
const bool pretty_print_ = false,
|
||||||
const bool ensure_ascii_ = false,
|
const bool ensure_ascii_ = false,
|
||||||
const std::size_t indent_step_ = 0,
|
const std::size_t indent_step_ = 0,
|
||||||
error_handler_t error_handler_ = error_handler_t::strict)
|
error_handler_t error_handler_ = error_handler_t::strict)
|
||||||
: o(&s)
|
: o(&s)
|
||||||
|
, number_buffer() // NOLINT(readability-redundant-member-init)
|
||||||
|
, string_buffer() // NOLINT(readability-redundant-member-init)
|
||||||
, indent_char(ichar)
|
, indent_char(ichar)
|
||||||
, pretty_print(pretty_print_)
|
, pretty_print(pretty_print_)
|
||||||
, ensure_ascii(ensure_ascii_)
|
, ensure_ascii(ensure_ascii_)
|
||||||
, indent_step(indent_step_)
|
, indent_step(indent_step_)
|
||||||
, error_handler(error_handler_)
|
, error_handler(error_handler_)
|
||||||
|
, write_buffer() // NOLINT(readability-redundant-member-init)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// deleted because of pointer members
|
// deleted because of pointer members
|
||||||
@@ -805,32 +808,20 @@ class serializer
|
|||||||
if (n >= 8)
|
if (n >= 8)
|
||||||
{
|
{
|
||||||
#if JSON_SCAN_VECTOR
|
#if JSON_SCAN_VECTOR
|
||||||
if (n >= 16)
|
if (!(n >= 16 ? copy_plain_vectors(d, p, n) : copy_plain_halves(d, p, n)))
|
||||||
{
|
{
|
||||||
if (!copy_plain_vectors(d, p, n))
|
return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if JSON_SCAN_VECTOR
|
|
||||||
if (!copy_plain_halves(d, p, n))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
const auto a = load_word<std::uint64_t>(p);
|
const auto a = load_word<std::uint64_t>(p);
|
||||||
const auto b = load_word<std::uint64_t>(p + n - 8);
|
const auto b = load_word<std::uint64_t>(p + n - 8);
|
||||||
if ((swar_not_plain(a) | swar_not_plain(b)) != 0)
|
if ((swar_not_plain(a) | swar_not_plain(b)) != 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
store_word(d, a);
|
|
||||||
store_word(d + n - 8, b);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
store_word(d, a);
|
||||||
|
store_word(d + n - 8, b);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (n >= 4)
|
else if (n >= 4)
|
||||||
{
|
{
|
||||||
@@ -2203,15 +2194,22 @@ class serializer
|
|||||||
/// the output of the serializer (non-owning; the adapter lives at the call site)
|
/// the output of the serializer (non-owning; the adapter lives at the call site)
|
||||||
output_adapter_protocol<char>* o = nullptr;
|
output_adapter_protocol<char>* o = nullptr;
|
||||||
|
|
||||||
// The three buffers below are left uninitialized: they are written before they
|
/// a character buffer left uninitialized: the buffers below are written
|
||||||
// are read (only the part written is ever read), and zeroing 1.6 KiB took
|
/// before they are read (only the part written is ever read), and zeroing
|
||||||
// more than half of what dumping a small value costs.
|
/// 1.6 KiB took more than half of what dumping a small value costs (the
|
||||||
|
/// user-provided constructor keeps the member initialization, which
|
||||||
|
/// -Weffc++ asks for, from zeroing them)
|
||||||
|
template<std::size_t N>
|
||||||
|
struct uninitialized_buffer : std::array<char, N>
|
||||||
|
{
|
||||||
|
uninitialized_buffer() noexcept {} // NOLINT(modernize-use-equals-default,hicpp-use-equals-default,cppcoreguidelines-pro-type-member-init,hicpp-member-init): see above
|
||||||
|
};
|
||||||
|
|
||||||
/// a (hopefully) large enough character buffer
|
/// a (hopefully) large enough character buffer
|
||||||
std::array<char, 64> number_buffer; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
uninitialized_buffer<64> number_buffer;
|
||||||
|
|
||||||
/// string buffer
|
/// string buffer
|
||||||
std::array<char, 512> string_buffer; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
uninitialized_buffer<512> string_buffer;
|
||||||
|
|
||||||
/// the indentation character
|
/// the indentation character
|
||||||
const char indent_char;
|
const char indent_char;
|
||||||
@@ -2231,7 +2229,7 @@ class serializer
|
|||||||
/// buffer collecting output before it is flushed to the output adapter, so
|
/// buffer collecting output before it is flushed to the output adapter, so
|
||||||
/// that the many small structural writes become few bulk writes
|
/// that the many small structural writes become few bulk writes
|
||||||
static constexpr std::size_t write_buffer_size = 1024;
|
static constexpr std::size_t write_buffer_size = 1024;
|
||||||
std::array<char, write_buffer_size> write_buffer; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
uninitialized_buffer<write_buffer_size> write_buffer;
|
||||||
/// number of valid bytes currently held in @ref write_buffer
|
/// number of valid bytes currently held in @ref write_buffer
|
||||||
std::size_t write_buffer_pos = 0;
|
std::size_t write_buffer_pos = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
Generated
+27
-29
@@ -30226,17 +30226,20 @@ class serializer
|
|||||||
being threaded through every call to @ref dump, @ref dump_internal and
|
being threaded through every call to @ref dump, @ref dump_internal and
|
||||||
@ref dump_iteratively.
|
@ref dump_iteratively.
|
||||||
*/
|
*/
|
||||||
serializer(output_adapter_protocol<char>& s, const char ichar, // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init): the buffers are written before they are read
|
serializer(output_adapter_protocol<char>& s, const char ichar,
|
||||||
const bool pretty_print_ = false,
|
const bool pretty_print_ = false,
|
||||||
const bool ensure_ascii_ = false,
|
const bool ensure_ascii_ = false,
|
||||||
const std::size_t indent_step_ = 0,
|
const std::size_t indent_step_ = 0,
|
||||||
error_handler_t error_handler_ = error_handler_t::strict)
|
error_handler_t error_handler_ = error_handler_t::strict)
|
||||||
: o(&s)
|
: o(&s)
|
||||||
|
, number_buffer() // NOLINT(readability-redundant-member-init)
|
||||||
|
, string_buffer() // NOLINT(readability-redundant-member-init)
|
||||||
, indent_char(ichar)
|
, indent_char(ichar)
|
||||||
, pretty_print(pretty_print_)
|
, pretty_print(pretty_print_)
|
||||||
, ensure_ascii(ensure_ascii_)
|
, ensure_ascii(ensure_ascii_)
|
||||||
, indent_step(indent_step_)
|
, indent_step(indent_step_)
|
||||||
, error_handler(error_handler_)
|
, error_handler(error_handler_)
|
||||||
|
, write_buffer() // NOLINT(readability-redundant-member-init)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
// deleted because of pointer members
|
// deleted because of pointer members
|
||||||
@@ -30949,32 +30952,20 @@ class serializer
|
|||||||
if (n >= 8)
|
if (n >= 8)
|
||||||
{
|
{
|
||||||
#if JSON_SCAN_VECTOR
|
#if JSON_SCAN_VECTOR
|
||||||
if (n >= 16)
|
if (!(n >= 16 ? copy_plain_vectors(d, p, n) : copy_plain_halves(d, p, n)))
|
||||||
{
|
{
|
||||||
if (!copy_plain_vectors(d, p, n))
|
return false;
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
#endif
|
|
||||||
{
|
|
||||||
#if JSON_SCAN_VECTOR
|
|
||||||
if (!copy_plain_halves(d, p, n))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#else
|
#else
|
||||||
const auto a = load_word<std::uint64_t>(p);
|
const auto a = load_word<std::uint64_t>(p);
|
||||||
const auto b = load_word<std::uint64_t>(p + n - 8);
|
const auto b = load_word<std::uint64_t>(p + n - 8);
|
||||||
if ((swar_not_plain(a) | swar_not_plain(b)) != 0)
|
if ((swar_not_plain(a) | swar_not_plain(b)) != 0)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
store_word(d, a);
|
|
||||||
store_word(d + n - 8, b);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
store_word(d, a);
|
||||||
|
store_word(d + n - 8, b);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (n >= 4)
|
else if (n >= 4)
|
||||||
{
|
{
|
||||||
@@ -32347,15 +32338,22 @@ class serializer
|
|||||||
/// the output of the serializer (non-owning; the adapter lives at the call site)
|
/// the output of the serializer (non-owning; the adapter lives at the call site)
|
||||||
output_adapter_protocol<char>* o = nullptr;
|
output_adapter_protocol<char>* o = nullptr;
|
||||||
|
|
||||||
// The three buffers below are left uninitialized: they are written before they
|
/// a character buffer left uninitialized: the buffers below are written
|
||||||
// are read (only the part written is ever read), and zeroing 1.6 KiB took
|
/// before they are read (only the part written is ever read), and zeroing
|
||||||
// more than half of what dumping a small value costs.
|
/// 1.6 KiB took more than half of what dumping a small value costs (the
|
||||||
|
/// user-provided constructor keeps the member initialization, which
|
||||||
|
/// -Weffc++ asks for, from zeroing them)
|
||||||
|
template<std::size_t N>
|
||||||
|
struct uninitialized_buffer : std::array<char, N>
|
||||||
|
{
|
||||||
|
uninitialized_buffer() noexcept {} // NOLINT(modernize-use-equals-default,hicpp-use-equals-default,cppcoreguidelines-pro-type-member-init,hicpp-member-init): see above
|
||||||
|
};
|
||||||
|
|
||||||
/// a (hopefully) large enough character buffer
|
/// a (hopefully) large enough character buffer
|
||||||
std::array<char, 64> number_buffer; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
uninitialized_buffer<64> number_buffer;
|
||||||
|
|
||||||
/// string buffer
|
/// string buffer
|
||||||
std::array<char, 512> string_buffer; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
uninitialized_buffer<512> string_buffer;
|
||||||
|
|
||||||
/// the indentation character
|
/// the indentation character
|
||||||
const char indent_char;
|
const char indent_char;
|
||||||
@@ -32375,7 +32373,7 @@ class serializer
|
|||||||
/// buffer collecting output before it is flushed to the output adapter, so
|
/// buffer collecting output before it is flushed to the output adapter, so
|
||||||
/// that the many small structural writes become few bulk writes
|
/// that the many small structural writes become few bulk writes
|
||||||
static constexpr std::size_t write_buffer_size = 1024;
|
static constexpr std::size_t write_buffer_size = 1024;
|
||||||
std::array<char, write_buffer_size> write_buffer; // NOLINT(cppcoreguidelines-pro-type-member-init,hicpp-member-init)
|
uninitialized_buffer<write_buffer_size> write_buffer;
|
||||||
/// number of valid bytes currently held in @ref write_buffer
|
/// number of valid bytes currently held in @ref write_buffer
|
||||||
std::size_t write_buffer_pos = 0;
|
std::size_t write_buffer_pos = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in new issue
Block a user