fix 32bit builds. closes #8625

32 bit build failure summary

Previously described in issue #8625 (comment 2630968343)

Some hash functions and struct asserts expect 64bit values but use size_t which fails on 32bit machines.

Not entirely sure if more code should be changed or added to accommodate for 32bit builds.

  • formid has a size_t assertion for the ESM::FormId struct

  • algorithm has size_t for has functions that look like they should be utin64_t

original issue text

original issue

system:

  • void linux (xbps-src build system)
  • gcc 14.4.1 20250405

Trying to build openmw for 32bit architectures fails in a few spots. (0.48.0 was fine)

build errors

components/esm/formid.hpp

size_t operator()(const ESM::FormId& formId) const
{
  static_assert(sizeof(ESM::FormId) == sizeof(size_t));

size_t is 4 on 32bit, 8 == 4 fails

Above it looks like the FormId struct has 3 uint32 and a string (which should be a pointer). size_t is 4 on 32bit, not 8. Using a hardcode works fine.

patch

--- components/esm/formid.hpp.orig	2025-07-16 08:08:41.922276482 -0400
+++ components/esm/formid.hpp	2025-07-16 08:31:26.832643473 -0400
@@ -49,12 +49,12 @@
     template <>
     struct hash<ESM::FormId>
     {
-        size_t operator()(const ESM::FormId& formId) const
+        uint64_t operator()(const ESM::FormId& formId) const
         {
-            static_assert(sizeof(ESM::FormId) == sizeof(size_t));
-            size_t s;
-            memcpy(&s, &formId, sizeof(size_t));
-            return hash<size_t>()(s);
+            static_assert(sizeof(ESM::FormId) == 8); // 8 uint32_t itmes
+            uint64_t s;
+            memcpy(&s, &formId, sizeof(ESM::FormId));
+            return hash<uint64_t>()(s);
         }
     };

components/misc/strings/algorithm.hpp

/builddir/openmw-0.49.0/./components/misc/strings/algorithm.hpp:91:31: error: narrowing conversion of '14695981039346656037' from 'long long unsigned int' to 'std::size_t' {aka 'unsigned int'} [-Wnarrowing]
   91 |             std::size_t hash{ 0xcbf29ce484222325ull };

/builddir/openmw-0.49.0/./components/misc/strings/algorithm.hpp:92:42: error: narrowing conversion of '1099511628211' from 'long long unsigned int' to 'std::size_t' {aka 'unsigned int'} [-Wnarrowing]
   92 |             constexpr std::size_t prime{ 0x00000100000001B3ull };
      |           

size_t 32bit issue again where going from (64)longs to size_t does not work. Not sure how this pans out for windows, think type names are different but also don't know the build.

patch

--- components/misc/strings/algorithm.hpp.orig	2025-07-16 08:24:42.712492950 -0400
+++ components/misc/strings/algorithm.hpp	2025-07-16 08:35:08.809678885 -0400
@@ -4,6 +4,7 @@
 #include "lower.hpp"
 
 #include <algorithm>
+#include <cstdint>
 #include <functional>
 #include <string>
 #include <string_view>
@@ -88,8 +89,8 @@
         constexpr std::size_t operator()(std::string_view str) const
         {
             // FNV-1a
-            std::size_t hash{ 0xcbf29ce484222325ull };
-            constexpr std::size_t prime{ 0x00000100000001B3ull };
+            std::uint64_t hash{ 0xcbf29ce484222325ull };
+            constexpr std::uint64_t prime{ 0x00000100000001B3ull };
             for (char c : str)
             {
                 hash ^= static_cast<std::size_t>(toLower(c));

Comments

Changing these to uint64 seems like the thing to do, but I'm not sure if there are other places that would need swapped out.

It looks like unint64_t is used in some places : components/esm/indexrefid.hpp

If there's any info that would help or build tests I can help with let me know. But, I don't actually even have morrowwind to test, I was just trying to upgrade because off ffmpeg7 support.

Merge request reports

Loading