From 40ac93b8f8b6e2f604fc561d0e33db3c0fceb137 Mon Sep 17 00:00:00 2001 From: Maxim Masiutin Date: Sun, 19 Apr 2026 07:19:17 +0200 Subject: [PATCH] Fix MultiArray::at(); use operator[] on hot paths Fix MultiArray::at() which was marked noexcept despite delegating to std::array::at() that throws on out-of-range. Per review feedback, at() now keeps standard bounds-checking semantics (only noexcept removed), and operator[] gains an assert for debug-mode safety. All eight correction history lookups in search.cpp (correction_value and update_correction_history) are switched from .at(us) to [us]. Passed STC: https://tests.stockfishchess.org/tests/view/69de7a735c67bee7d241ff92 LLR: 2.96 (-2.94,2.94) <-1.75,0.25> Total: 77536 W: 20031 L: 19860 D: 37645 Ptnml(0-2): 221, 8411, 21338, 8572, 226 closes https://github.com/official-stockfish/Stockfish/pull/6734 No functional change --- src/misc.h | 14 ++++++++++---- src/search.cpp | 16 ++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/misc.h b/src/misc.h index 4ea7d99ac..d763c50d3 100644 --- a/src/misc.h +++ b/src/misc.h @@ -266,11 +266,17 @@ class MultiArray { using reverse_iterator = typename ArrayType::reverse_iterator; using const_reverse_iterator = typename ArrayType::const_reverse_iterator; - constexpr auto& at(size_type index) noexcept { return data_.at(index); } - constexpr const auto& at(size_type index) const noexcept { return data_.at(index); } + constexpr auto& at(size_type index) { return data_.at(index); } + constexpr const auto& at(size_type index) const { return data_.at(index); } - constexpr auto& operator[](size_type index) noexcept { return data_[index]; } - constexpr const auto& operator[](size_type index) const noexcept { return data_[index]; } + constexpr auto& operator[](size_type index) noexcept { + assert(index < Size); + return data_[index]; + } + constexpr const auto& operator[](size_type index) const noexcept { + assert(index < Size); + return data_[index]; + } constexpr auto& front() noexcept { return data_.front(); } constexpr const auto& front() const noexcept { return data_.front(); } diff --git a/src/search.cpp b/src/search.cpp index 02ac998a6..99f10bdc8 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -85,10 +85,10 @@ int correction_value(const Worker& w, const Position& pos, const Stack* const ss const Color us = pos.side_to_move(); const auto m = (ss - 1)->currentMove; const auto& shared = w.sharedHistory; - const int pcv = shared.pawn_correction_entry(pos).at(us).pawn; - const int micv = shared.minor_piece_correction_entry(pos).at(us).minor; - const int wnpcv = shared.nonpawn_correction_entry(pos).at(us).nonPawnWhite; - const int bnpcv = shared.nonpawn_correction_entry(pos).at(us).nonPawnBlack; + const int pcv = shared.pawn_correction_entry(pos)[us].pawn; + const int micv = shared.minor_piece_correction_entry(pos)[us].minor; + const int wnpcv = shared.nonpawn_correction_entry(pos)[us].nonPawnWhite; + const int bnpcv = shared.nonpawn_correction_entry(pos)[us].nonPawnBlack; const int cntcv = m.is_ok() ? (*(ss - 2)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()] + (*(ss - 4)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()] @@ -113,10 +113,10 @@ void update_correction_history(const Position& pos, constexpr int nonPawnWeight = 187; auto& shared = workerThread.sharedHistory; - shared.pawn_correction_entry(pos).at(us).pawn << bonus; - shared.minor_piece_correction_entry(pos).at(us).minor << bonus * 153 / 128; - shared.nonpawn_correction_entry(pos).at(us).nonPawnWhite << bonus * nonPawnWeight / 128; - shared.nonpawn_correction_entry(pos).at(us).nonPawnBlack << bonus * nonPawnWeight / 128; + shared.pawn_correction_entry(pos)[us].pawn << bonus; + shared.minor_piece_correction_entry(pos)[us].minor << bonus * 153 / 128; + shared.nonpawn_correction_entry(pos)[us].nonPawnWhite << bonus * nonPawnWeight / 128; + shared.nonpawn_correction_entry(pos)[us].nonPawnBlack << bonus * nonPawnWeight / 128; if (m.is_ok()) {