From 3e9602206f3e79097b44a86a397c0194a979bda5 Mon Sep 17 00:00:00 2001 From: Ben Deane Date: Mon, 24 Nov 2025 14:56:37 -0700 Subject: [PATCH] :bug: Fix field extent Problem: - There is an off-by-one error in the field extent code such that a message whose "rightmost" field is a single bit on a data boundary computes its storage wrongly. Solution: - Fix off-by-one error. --- include/msg/field.hpp | 4 ++-- test/msg/message.cpp | 9 +++++++++ 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/include/msg/field.hpp b/include/msg/field.hpp index 1947e1d5..904fb950 100644 --- a/include/msg/field.hpp +++ b/include/msg/field.hpp @@ -206,8 +206,8 @@ struct bits_locator_t { } template constexpr static auto extent_in() -> std::size_t { - constexpr auto msb = Lsb + BitSize - 1; - constexpr auto msb_extent = (msb + CHAR_BIT - 1) / CHAR_BIT; + constexpr auto msb_exclusive = Lsb + BitSize; + constexpr auto msb_extent = (msb_exclusive + CHAR_BIT - 1) / CHAR_BIT; constexpr auto base_extent = Index * sizeof(std::uint32_t); constexpr auto extent = base_extent + msb_extent; return (extent + sizeof(T) - 1) / sizeof(T); diff --git a/test/msg/message.cpp b/test/msg/message.cpp index 929ba563..88a3e1df 100644 --- a/test/msg/message.cpp +++ b/test/msg/message.cpp @@ -840,3 +840,12 @@ TEST_CASE("message with uninitialized field", "[message]") { auto data = msg.data(); CHECK(data[0] == 1); } + +TEST_CASE("field extents", "[message]") { + using f1 = msg::detail::bits_locator_t<0, 1, 0>; + STATIC_CHECK(f1::extent_in() == 1); + STATIC_CHECK(f1::extent_in() == 1); + using f2 = msg::detail::bits_locator_t<0, 1, 31>; + STATIC_CHECK(f2::extent_in() == 1); + STATIC_CHECK(f2::extent_in() == 4); +}