dfhack icon indicating copy to clipboard operation
dfhack copied to clipboard

df globals are effectively `const` but aren't actually `const`

Open ab9rf opened this issue 5 months ago • 0 comments

@dhthwy's PR #5583 identified an issue that is leading to suboptimal code generation in code that references certain DF global variables. We currently deal with these objects by having static global pointers that point to the memory locations in DF's memory where these objects live. These pointers are effectively constants, in that they, after being set during symbols.xml parsing, will never subsequently change, and so code that references them after initial processing should be able to assume that these pointers will not change. However, they're not marked as const, and so the compilers we use will not use optimizations that rely on this. @dhthwy's PR identifies at least a few places where this occurs in fairly hot loops, where it might well lead to meaningful performance differences, at least under some circumstances.

@dhthwy's PR is a piecemeal solution to this problem: the code in that PR just creates a local copy of the pointer, and as that pointer won't change during the loop, the compiler will optimize uses of it on that basis. However, this requires a complex access paradigm for this objects which I don't very much like.

The issue is that these pointers are static non-block variables in DFHack's namespace, which prevents us from declaring them const: const static non-block variables must be initialized during program startup (which, for DFHack, is at DLL load), but we can't initialize them until after we've processed symbols.xml, which prevents them from being declared as const in DFHack. The compiler would be free to assume that the static initialization is the value for all time, and might therefore generate code that ignored any initialization of these values (such as via using const_cast to remove the const attribute for one-time initialization. Modifying an object declared as const through a non-const pointer obtained via const_cast is, after all, UB.

I don't yet have a solution for this problem that I like, but @dhthwy's experience with using gcc 15 to build DFHack, and the performance issues he reported, suggests that we will, at some point, need to address this, and so this issue serves to memorialize the issue and the thoughts I've had so far in regard to it.

ab9rf avatar Sep 25 '25 19:09 ab9rf