From 0595b05a82a870e4a74956678f3abfab834acd76 Mon Sep 17 00:00:00 2001 From: Jan Schlosser Date: Mon, 5 Oct 2026 11:29:18 +0200 Subject: [PATCH 1/2] refactor(tutorial): replace snprintf with std::copy_n in providers Build the payload as a std::string and copy it into the sample array with std::copy_n, truncating to the array capacity and null-terminating. This removes the snprintf/memcpy calls and the pointer arithmetic, and with them the cppcoreguidelines-pro-type-vararg and pro-bounds-pointer-arithmetic clang-tidy findings, while simplifying the tutorial code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../mw/com/doc/tutorial/chapter_1/provider.cpp | 18 +++++++----------- .../tutorial/chapter_10/provider/provider.cpp | 18 +++++++----------- .../chapter_12/provider/skeleton_component.cpp | 17 ++++++----------- .../tutorial/chapter_2/provider/provider.cpp | 18 +++++++----------- .../tutorial/chapter_6/provider/provider.cpp | 18 +++++++----------- 5 files changed, 34 insertions(+), 55 deletions(-) diff --git a/score/mw/com/doc/tutorial/chapter_1/provider.cpp b/score/mw/com/doc/tutorial/chapter_1/provider.cpp index aeb052e445..371ead3cff 100644 --- a/score/mw/com/doc/tutorial/chapter_1/provider.cpp +++ b/score/mw/com/doc/tutorial/chapter_1/provider.cpp @@ -13,10 +13,10 @@ #include "score/mw/com/doc/tutorial/chapter_1/hello_world_service.h" #include "score/mw/com/types.h" +#include #include #include -#include -#include +#include constexpr std::string_view kHelloWorld{"Hello World"}; namespace @@ -73,15 +73,11 @@ int main() } // Write new event data to slot - std::memcpy(sample_allocatee_ptr.value().Get()->data(), kHelloWorld.data(), kHelloWorld.size()); - auto* buf = sample_allocatee_ptr.value().Get()->data(); - const auto remaining = sample_allocatee_ptr.value().Get()->size() - kHelloWorld.size(); - const auto chars_written = std::snprintf(buf + kHelloWorld.size(), remaining, "%zu", send_counter); - if (chars_written < 0) - { - std::cerr << "Failed to write 'send_counter' to sample_allocatee_ptr!" << std::endl; - exit(1); - } + const std::string message = std::string{kHelloWorld} + std::to_string(send_counter); + auto& sample = *sample_allocatee_ptr.value().Get(); + auto* buf = sample.data(); + const auto chars_to_copy = std::min(message.size(), sample.size() - 1U); + *std::copy_n(message.begin(), chars_to_copy, sample.begin()) = '\0'; // Send the new event sample (make it visible to potential consumers) // [hello-world-send-start] diff --git a/score/mw/com/doc/tutorial/chapter_10/provider/provider.cpp b/score/mw/com/doc/tutorial/chapter_10/provider/provider.cpp index d0419acb0e..7ac1b96843 100644 --- a/score/mw/com/doc/tutorial/chapter_10/provider/provider.cpp +++ b/score/mw/com/doc/tutorial/chapter_10/provider/provider.cpp @@ -13,10 +13,10 @@ #include "score/mw/com/doc/tutorial/chapter_10/hello_world_service.h" #include "score/mw/com/types.h" +#include #include #include -#include -#include +#include constexpr std::string_view kHelloWorld{"Hello World"}; namespace @@ -63,15 +63,11 @@ int main() } // Write new event data to slot - std::memcpy(sample_allocatee_ptr.value().Get()->data(), kHelloWorld.data(), kHelloWorld.size()); - auto* buf = sample_allocatee_ptr.value().Get()->data(); - const auto remaining = sample_allocatee_ptr.value().Get()->size() - kHelloWorld.size(); - const auto chars_written = std::snprintf(buf + kHelloWorld.size(), remaining, "%zu", send_counter); - if (chars_written < 0) - { - std::cerr << "Failed to write 'send_counter' to sample_allocatee_ptr!" << std::endl; - exit(1); - } + const std::string message = std::string{kHelloWorld} + std::to_string(send_counter); + auto& sample = *sample_allocatee_ptr.value().Get(); + auto* buf = sample.data(); + const auto chars_to_copy = std::min(message.size(), sample.size() - 1U); + *std::copy_n(message.begin(), chars_to_copy, sample.begin()) = '\0'; // Send the new event sample (make it visible to potential consumers) auto send_result = hello_world_service_instance.message.Send(std::move(sample_allocatee_ptr.value())); diff --git a/score/mw/com/doc/tutorial/chapter_12/provider/skeleton_component.cpp b/score/mw/com/doc/tutorial/chapter_12/provider/skeleton_component.cpp index 82b05c98c2..0f026352af 100644 --- a/score/mw/com/doc/tutorial/chapter_12/provider/skeleton_component.cpp +++ b/score/mw/com/doc/tutorial/chapter_12/provider/skeleton_component.cpp @@ -12,8 +12,7 @@ ********************************************************************************/ #include "score/mw/com/doc/tutorial/chapter_12/provider/skeleton_component.h" -#include -#include +#include #include #include #include @@ -46,15 +45,11 @@ SkeletonComponent::SendSampleResult SkeletonComponent::SendSample(std::size_t se return SendSampleResult::kNoSampleAllocated; } - std::memcpy(sample_allocatee_ptr.value().Get()->data(), kHelloWorld.data(), kHelloWorld.size()); - auto* buf = sample_allocatee_ptr.value().Get()->data(); - const auto remaining = sample_allocatee_ptr.value().Get()->size() - kHelloWorld.size(); - const auto chars_written = std::snprintf(buf + kHelloWorld.size(), remaining, "%zu", send_counter); - if (chars_written < 0) - { - std::cerr << "Failed to write 'send_counter' to sample_allocatee_ptr!" << std::endl; - return SendSampleResult::kFatalError; - } + const std::string message = std::string{kHelloWorld} + std::to_string(send_counter); + auto& sample = *sample_allocatee_ptr.value().Get(); + auto* buf = sample.data(); + const auto chars_to_copy = std::min(message.size(), sample.size() - 1U); + *std::copy_n(message.begin(), chars_to_copy, sample.begin()) = '\0'; const std::string payload_for_log{buf}; auto send_result = hello_world_skeleton_->message.Send(std::move(sample_allocatee_ptr.value())); diff --git a/score/mw/com/doc/tutorial/chapter_2/provider/provider.cpp b/score/mw/com/doc/tutorial/chapter_2/provider/provider.cpp index 1bbd835098..b1476ac69b 100644 --- a/score/mw/com/doc/tutorial/chapter_2/provider/provider.cpp +++ b/score/mw/com/doc/tutorial/chapter_2/provider/provider.cpp @@ -13,10 +13,10 @@ #include "score/mw/com/doc/tutorial/chapter_2/hello_world_service.h" #include "score/mw/com/types.h" +#include #include #include -#include -#include +#include constexpr std::string_view kHelloWorld{"Hello World"}; namespace @@ -63,15 +63,11 @@ int main() } // Write new event data to slot - std::memcpy(sample_allocatee_ptr.value().Get()->data(), kHelloWorld.data(), kHelloWorld.size()); - auto* buf = sample_allocatee_ptr.value().Get()->data(); - const auto remaining = sample_allocatee_ptr.value().Get()->size() - kHelloWorld.size(); - const auto chars_written = std::snprintf(buf + kHelloWorld.size(), remaining, "%zu", send_counter); - if (chars_written < 0) - { - std::cerr << "Failed to write 'send_counter' to sample_allocatee_ptr!" << std::endl; - exit(1); - } + const std::string message = std::string{kHelloWorld} + std::to_string(send_counter); + auto& sample = *sample_allocatee_ptr.value().Get(); + auto* buf = sample.data(); + const auto chars_to_copy = std::min(message.size(), sample.size() - 1U); + *std::copy_n(message.begin(), chars_to_copy, sample.begin()) = '\0'; // Send the new event sample (make it visible to potential consumers) auto send_result = hello_world_service_instance.message.Send(std::move(sample_allocatee_ptr.value())); diff --git a/score/mw/com/doc/tutorial/chapter_6/provider/provider.cpp b/score/mw/com/doc/tutorial/chapter_6/provider/provider.cpp index fa74507c15..ea1d09be36 100644 --- a/score/mw/com/doc/tutorial/chapter_6/provider/provider.cpp +++ b/score/mw/com/doc/tutorial/chapter_6/provider/provider.cpp @@ -13,10 +13,10 @@ #include "score/mw/com/doc/tutorial/chapter_6/hello_world_service.h" #include "score/mw/com/types.h" +#include #include #include -#include -#include +#include constexpr std::string_view kHelloWorld{"Hello World"}; namespace @@ -63,15 +63,11 @@ int main() } // Write new event data to slot - std::memcpy(sample_allocatee_ptr.value().Get()->data(), kHelloWorld.data(), kHelloWorld.size()); - auto* buf = sample_allocatee_ptr.value().Get()->data(); - const auto remaining = sample_allocatee_ptr.value().Get()->size() - kHelloWorld.size(); - const auto chars_written = std::snprintf(buf + kHelloWorld.size(), remaining, "%zu", send_counter); - if (chars_written < 0) - { - std::cerr << "Failed to write 'send_counter' to sample_allocatee_ptr!" << std::endl; - exit(1); - } + const std::string message = std::string{kHelloWorld} + std::to_string(send_counter); + auto& sample = *sample_allocatee_ptr.value().Get(); + auto* buf = sample.data(); + const auto chars_to_copy = std::min(message.size(), sample.size() - 1U); + *std::copy_n(message.begin(), chars_to_copy, sample.begin()) = '\0'; // Send the new event sample (make it visible to potential consumers) auto send_result = hello_world_service_instance.message.Send(std::move(sample_allocatee_ptr.value())); From dffc637779a45cc9012b74cb467234583a267d0e Mon Sep 17 00:00:00 2001 From: Jan Schlosser Date: Mon, 5 Oct 2026 15:17:51 +0200 Subject: [PATCH 2/2] docs(tutorial): adjust chapter 12 literalinclude line range Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- score/mw/com/doc/tutorial/chapter_12/README.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/score/mw/com/doc/tutorial/chapter_12/README.rst b/score/mw/com/doc/tutorial/chapter_12/README.rst index d1b40704b6..005a88a1b7 100644 --- a/score/mw/com/doc/tutorial/chapter_12/README.rst +++ b/score/mw/com/doc/tutorial/chapter_12/README.rst @@ -131,7 +131,7 @@ The `SkeletonComponent` implementation encapsulates offer/allocate/send behavior .. literalinclude:: provider/skeleton_component.cpp :language: cpp - :lines: 27-69 + :lines: 26-64 :caption: provider/skeleton_component.cpp