From 45c61dd00e2c686bc0a3018a448c20e3295a550c Mon Sep 17 00:00:00 2001 From: Fr0zka Date: Mon, 17 Aug 2026 00:50:34 +0200 Subject: [PATCH] fix(opstack): hoist the acquired column box out of the integer-XY scope VoxelDensityOpStack.cpp(832): C2065 'Box' undeclared. The six-box LRU refactor moved acquisition to `FColumnBox& Box = Cache.Acquire(...)` inside `if (bIntegerXY)`, but the Computed flag is set after the column is computed, outside that block. The previous single-box version had Box at function scope so the write-back compiled. Hoists `FColumnBox* AcquiredBox` beside MemoColumn and writes back through it. The guard becomes `if (AcquiredBox)` instead of `if (bIntegerXY)`: non-null implies the integer path, so the pointer proves its own safety rather than relying on two conditions staying in agreement. No caching or logic change. Other Box. uses (761-763) are in scope, verified. Co-Authored-By: Claude Opus 5 --- OPSTACK-PROGRESS.md | 17 +++++++++++++++++ .../VoxelForge/Private/VoxelDensityOpStack.cpp | 8 +++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/OPSTACK-PROGRESS.md b/OPSTACK-PROGRESS.md index ba050de..9cb4b63 100644 --- a/OPSTACK-PROGRESS.md +++ b/OPSTACK-PROGRESS.md @@ -4214,3 +4214,20 @@ The dirty candidate diffs were preserved as named, recoverable stashes before cl `../VF-approach-A` and `../VF-approach-B` were then removed from Git's worktree list and their directories removed. Stashing was a cleanup-safety deviation only; it did not alter the landed code. + +## 2026-08-16 (o) — build break in the six-box LRU: `Box` used after its scope closed + +`VoxelDensityOpStack.cpp(832): error C2065: 'Box' : identificateur non déclaré` + +Sol's single-box → six-box refactor changed the acquisition to +`FColumnBox& Box = Cache.Acquire(...)` **inside** `if (bIntegerXY)`, but the `Computed` flag is only +set *after* the column is computed, further down and **outside** that block. The old single-box +version had `Box` at function scope, so the write-back compiled; the reference did not. + +Fixed by hoisting `FColumnBox* AcquiredBox = nullptr;` beside `MemoColumn` and writing back through +it. The guard is now `if (AcquiredBox)` rather than `if (bIntegerXY)` — **non-null ⇔ integer path**, +so the pointer proves its own safety instead of relying on two conditions staying in agreement. + +Swept the file: the only other `Box.` uses (761–763) are inside the `if` and in scope. Not a logic +error and not a caching change — a scope slip, invisible in review because the diff showed both +halves separately. Still unbuilt beyond this compile fix. diff --git a/Source/VoxelForge/Private/VoxelDensityOpStack.cpp b/Source/VoxelForge/Private/VoxelDensityOpStack.cpp index cf2f58f..33b863b 100644 --- a/Source/VoxelForge/Private/VoxelDensityOpStack.cpp +++ b/Source/VoxelForge/Private/VoxelDensityOpStack.cpp @@ -740,6 +740,11 @@ namespace const bool bIntegerXY = WorldX == FMath::FloorToFloat(WorldX) && WorldY == FMath::FloorToFloat(WorldY); FColumn* MemoColumn = &DirectColumn; + // ⚠️ La boîte acquise doit survivre au `if` : le drapeau `Computed` n'est posé qu'APRÈS + // le calcul, plus bas, hors de cette portée. Non nul ⇔ chemin XY entier. + // The acquired box must outlive the `if`: the `Computed` flag is only set AFTER the + // column is computed, further down and outside this scope. Non-null <=> integer path. + FColumnBox* AcquiredBox = nullptr; int32 CI = 0; bool bNeedsCompute = true; @@ -751,6 +756,7 @@ namespace // Acquire vérifie la clé uint64 complète et les bornes exactes avant de dériver CI. // Acquire checks the exact uint64 key and exact bounds before deriving CI. FColumnBox& Box = Cache.Acquire(IX, IY, ColumnKey); + AcquiredBox = &Box; CI = (IY - Box.BaseY) * FColumnBox::Dim + (IX - Box.BaseX); MemoColumn = &Box.Cols[CI]; @@ -829,7 +835,7 @@ namespace if (Slope > KINDA_SMALL_NUMBER) { C.DirX = GX / Slope; C.DirY = GY / Slope; } } - if (bIntegerXY) { Box.Computed[CI] = true; } + if (AcquiredBox) { AcquiredBox->Computed[CI] = true; } } return *MemoColumn; }