From 86a77ff8eb6c4e942a4ab9ec9172073517ad61d6 Mon Sep 17 00:00:00 2001 From: Yuval Tassa Date: Wed, 19 Nov 2025 07:55:00 -0800 Subject: [PATCH] Change `mjtSize` from `uint64_t` to `int64_t`. This change makes `mjtSize` a signed, rather than unsigned 64-bit integer. While sizes are non-negative, the type promotion rules for unsigned integers can lead to unituitive downstream bugs, and 8 billion terabytes are enough bytes. PiperOrigin-RevId: 834292964 Change-Id: Iea9c47c2a5d80fde63851a543d59ed0549db0f01 --- doc/APIreference/APItypes.rst | 2 +- doc/changelog.rst | 6 +- include/mujoco/mjtnum.h | 7 +- src/engine/engine_print.c | 7 +- unity/Runtime/Bindings/MjBindings.cs | 270 +++++++++++++-------------- 5 files changed, 149 insertions(+), 143 deletions(-) diff --git a/doc/APIreference/APItypes.rst b/doc/APIreference/APItypes.rst index 07498d5b..b1997964 100644 --- a/doc/APIreference/APItypes.rst +++ b/doc/APIreference/APItypes.rst @@ -100,7 +100,7 @@ Size type used to represent buffer sizes. .. code-block:: C - typedef uint64_t mjtSize; + typedef int64_t mjtSize; .. _tyEnums: diff --git a/doc/changelog.rst b/doc/changelog.rst index 9648c15d..8dcff282 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -29,7 +29,11 @@ General - ``sidesite -> MjsSite|None`` - ``coef -> real`` - ``divisor -> real`` -- Non-breaking API change: :ref:`mj_sizeModel` now returns an :ref:`mjtSize` rather than an ``int``. + +- Non-breaking ABI changes: + + - :ref:`mjtSize` is now defined as ``int64_t`` rather than ``uint64_t`` to avoid future type-promotion bugs. + - :ref:`mj_sizeModel` now returns an :ref:`mjtSize` rather than an ``int``. MJX ^^^ diff --git a/include/mujoco/mjtnum.h b/include/mujoco/mjtnum.h index 838357a2..845ce73b 100644 --- a/include/mujoco/mjtnum.h +++ b/include/mujoco/mjtnum.h @@ -17,6 +17,7 @@ #include + //---------------------------------- floating-point definition ------------------------------------- // floating point data type and minval @@ -30,15 +31,15 @@ -//-------------------------------------- byte definition ------------------------------------------- +//---------------------------------- byte definition ----------------------------------------------- typedef unsigned char mjtByte; // used for true/false -//-------------------------------------- size definition ------------------------------------------- +//---------------------------------- size definition ----------------------------------------------- -typedef uint64_t mjtSize; // used for buffer sizes +typedef int64_t mjtSize; // used for buffer sizes diff --git a/src/engine/engine_print.c b/src/engine/engine_print.c index e05984cf..64a520fa 100644 --- a/src/engine/engine_print.c +++ b/src/engine/engine_print.c @@ -14,6 +14,7 @@ #include "engine/engine_print.h" +#include // IWYU pragma: keep #include #include #include @@ -41,7 +42,7 @@ #define FLOAT_FORMAT "% -9.2g" #define FLOAT_FORMAT_MAX_LEN 20 #define INT_FORMAT " %d" -#define SIZE_T_FORMAT " %zu" +#define SIZE_FORMAT " %" PRId64 #define NAME_FORMAT "%-21s" @@ -543,7 +544,7 @@ void mj_printFormattedModel(const mjModel* m, const char* filename, const char* if (m->name) { \ const char* format = _Generic( \ m->name, \ - size_t : SIZE_T_FORMAT, \ + mjtSize : SIZE_FORMAT, \ default : INT_FORMAT); \ fprintf(fp, NAME_FORMAT, " " #name); \ fprintf(fp, format, m->name); \ @@ -1146,7 +1147,7 @@ void mj_printFormattedData(const mjModel* m, const mjData* d, const char* filena const char* format = _Generic( \ d->name, \ int : INT_FORMAT, \ - size_t : SIZE_T_FORMAT, \ + mjtSize : SIZE_FORMAT, \ default : NULL); \ if (format) { \ fprintf(fp, " "); \ diff --git a/unity/Runtime/Bindings/MjBindings.cs b/unity/Runtime/Bindings/MjBindings.cs index 37b3dfef..a1c13b76 100644 --- a/unity/Runtime/Bindings/MjBindings.cs +++ b/unity/Runtime/Bindings/MjBindings.cs @@ -740,142 +740,142 @@ public unsafe struct mjSolverStat_ { [StructLayout(LayoutKind.Sequential)] public unsafe struct mjData_ { - public UInt64 narena; - public UInt64 nbuffer; + public Int64 narena; + public Int64 nbuffer; public int nplugin; public UIntPtr pstack; public UIntPtr pbase; public UIntPtr parena; - public UInt64 maxuse_stack; - public UInt64 maxuse_threadstack0; - public UInt64 maxuse_threadstack1; - public UInt64 maxuse_threadstack2; - public UInt64 maxuse_threadstack3; - public UInt64 maxuse_threadstack4; - public UInt64 maxuse_threadstack5; - public UInt64 maxuse_threadstack6; - public UInt64 maxuse_threadstack7; - public UInt64 maxuse_threadstack8; - public UInt64 maxuse_threadstack9; - public UInt64 maxuse_threadstack10; - public UInt64 maxuse_threadstack11; - public UInt64 maxuse_threadstack12; - public UInt64 maxuse_threadstack13; - public UInt64 maxuse_threadstack14; - public UInt64 maxuse_threadstack15; - public UInt64 maxuse_threadstack16; - public UInt64 maxuse_threadstack17; - public UInt64 maxuse_threadstack18; - public UInt64 maxuse_threadstack19; - public UInt64 maxuse_threadstack20; - public UInt64 maxuse_threadstack21; - public UInt64 maxuse_threadstack22; - public UInt64 maxuse_threadstack23; - public UInt64 maxuse_threadstack24; - public UInt64 maxuse_threadstack25; - public UInt64 maxuse_threadstack26; - public UInt64 maxuse_threadstack27; - public UInt64 maxuse_threadstack28; - public UInt64 maxuse_threadstack29; - public UInt64 maxuse_threadstack30; - public UInt64 maxuse_threadstack31; - public UInt64 maxuse_threadstack32; - public UInt64 maxuse_threadstack33; - public UInt64 maxuse_threadstack34; - public UInt64 maxuse_threadstack35; - public UInt64 maxuse_threadstack36; - public UInt64 maxuse_threadstack37; - public UInt64 maxuse_threadstack38; - public UInt64 maxuse_threadstack39; - public UInt64 maxuse_threadstack40; - public UInt64 maxuse_threadstack41; - public UInt64 maxuse_threadstack42; - public UInt64 maxuse_threadstack43; - public UInt64 maxuse_threadstack44; - public UInt64 maxuse_threadstack45; - public UInt64 maxuse_threadstack46; - public UInt64 maxuse_threadstack47; - public UInt64 maxuse_threadstack48; - public UInt64 maxuse_threadstack49; - public UInt64 maxuse_threadstack50; - public UInt64 maxuse_threadstack51; - public UInt64 maxuse_threadstack52; - public UInt64 maxuse_threadstack53; - public UInt64 maxuse_threadstack54; - public UInt64 maxuse_threadstack55; - public UInt64 maxuse_threadstack56; - public UInt64 maxuse_threadstack57; - public UInt64 maxuse_threadstack58; - public UInt64 maxuse_threadstack59; - public UInt64 maxuse_threadstack60; - public UInt64 maxuse_threadstack61; - public UInt64 maxuse_threadstack62; - public UInt64 maxuse_threadstack63; - public UInt64 maxuse_threadstack64; - public UInt64 maxuse_threadstack65; - public UInt64 maxuse_threadstack66; - public UInt64 maxuse_threadstack67; - public UInt64 maxuse_threadstack68; - public UInt64 maxuse_threadstack69; - public UInt64 maxuse_threadstack70; - public UInt64 maxuse_threadstack71; - public UInt64 maxuse_threadstack72; - public UInt64 maxuse_threadstack73; - public UInt64 maxuse_threadstack74; - public UInt64 maxuse_threadstack75; - public UInt64 maxuse_threadstack76; - public UInt64 maxuse_threadstack77; - public UInt64 maxuse_threadstack78; - public UInt64 maxuse_threadstack79; - public UInt64 maxuse_threadstack80; - public UInt64 maxuse_threadstack81; - public UInt64 maxuse_threadstack82; - public UInt64 maxuse_threadstack83; - public UInt64 maxuse_threadstack84; - public UInt64 maxuse_threadstack85; - public UInt64 maxuse_threadstack86; - public UInt64 maxuse_threadstack87; - public UInt64 maxuse_threadstack88; - public UInt64 maxuse_threadstack89; - public UInt64 maxuse_threadstack90; - public UInt64 maxuse_threadstack91; - public UInt64 maxuse_threadstack92; - public UInt64 maxuse_threadstack93; - public UInt64 maxuse_threadstack94; - public UInt64 maxuse_threadstack95; - public UInt64 maxuse_threadstack96; - public UInt64 maxuse_threadstack97; - public UInt64 maxuse_threadstack98; - public UInt64 maxuse_threadstack99; - public UInt64 maxuse_threadstack100; - public UInt64 maxuse_threadstack101; - public UInt64 maxuse_threadstack102; - public UInt64 maxuse_threadstack103; - public UInt64 maxuse_threadstack104; - public UInt64 maxuse_threadstack105; - public UInt64 maxuse_threadstack106; - public UInt64 maxuse_threadstack107; - public UInt64 maxuse_threadstack108; - public UInt64 maxuse_threadstack109; - public UInt64 maxuse_threadstack110; - public UInt64 maxuse_threadstack111; - public UInt64 maxuse_threadstack112; - public UInt64 maxuse_threadstack113; - public UInt64 maxuse_threadstack114; - public UInt64 maxuse_threadstack115; - public UInt64 maxuse_threadstack116; - public UInt64 maxuse_threadstack117; - public UInt64 maxuse_threadstack118; - public UInt64 maxuse_threadstack119; - public UInt64 maxuse_threadstack120; - public UInt64 maxuse_threadstack121; - public UInt64 maxuse_threadstack122; - public UInt64 maxuse_threadstack123; - public UInt64 maxuse_threadstack124; - public UInt64 maxuse_threadstack125; - public UInt64 maxuse_threadstack126; - public UInt64 maxuse_threadstack127; - public UInt64 maxuse_arena; + public Int64 maxuse_stack; + public Int64 maxuse_threadstack0; + public Int64 maxuse_threadstack1; + public Int64 maxuse_threadstack2; + public Int64 maxuse_threadstack3; + public Int64 maxuse_threadstack4; + public Int64 maxuse_threadstack5; + public Int64 maxuse_threadstack6; + public Int64 maxuse_threadstack7; + public Int64 maxuse_threadstack8; + public Int64 maxuse_threadstack9; + public Int64 maxuse_threadstack10; + public Int64 maxuse_threadstack11; + public Int64 maxuse_threadstack12; + public Int64 maxuse_threadstack13; + public Int64 maxuse_threadstack14; + public Int64 maxuse_threadstack15; + public Int64 maxuse_threadstack16; + public Int64 maxuse_threadstack17; + public Int64 maxuse_threadstack18; + public Int64 maxuse_threadstack19; + public Int64 maxuse_threadstack20; + public Int64 maxuse_threadstack21; + public Int64 maxuse_threadstack22; + public Int64 maxuse_threadstack23; + public Int64 maxuse_threadstack24; + public Int64 maxuse_threadstack25; + public Int64 maxuse_threadstack26; + public Int64 maxuse_threadstack27; + public Int64 maxuse_threadstack28; + public Int64 maxuse_threadstack29; + public Int64 maxuse_threadstack30; + public Int64 maxuse_threadstack31; + public Int64 maxuse_threadstack32; + public Int64 maxuse_threadstack33; + public Int64 maxuse_threadstack34; + public Int64 maxuse_threadstack35; + public Int64 maxuse_threadstack36; + public Int64 maxuse_threadstack37; + public Int64 maxuse_threadstack38; + public Int64 maxuse_threadstack39; + public Int64 maxuse_threadstack40; + public Int64 maxuse_threadstack41; + public Int64 maxuse_threadstack42; + public Int64 maxuse_threadstack43; + public Int64 maxuse_threadstack44; + public Int64 maxuse_threadstack45; + public Int64 maxuse_threadstack46; + public Int64 maxuse_threadstack47; + public Int64 maxuse_threadstack48; + public Int64 maxuse_threadstack49; + public Int64 maxuse_threadstack50; + public Int64 maxuse_threadstack51; + public Int64 maxuse_threadstack52; + public Int64 maxuse_threadstack53; + public Int64 maxuse_threadstack54; + public Int64 maxuse_threadstack55; + public Int64 maxuse_threadstack56; + public Int64 maxuse_threadstack57; + public Int64 maxuse_threadstack58; + public Int64 maxuse_threadstack59; + public Int64 maxuse_threadstack60; + public Int64 maxuse_threadstack61; + public Int64 maxuse_threadstack62; + public Int64 maxuse_threadstack63; + public Int64 maxuse_threadstack64; + public Int64 maxuse_threadstack65; + public Int64 maxuse_threadstack66; + public Int64 maxuse_threadstack67; + public Int64 maxuse_threadstack68; + public Int64 maxuse_threadstack69; + public Int64 maxuse_threadstack70; + public Int64 maxuse_threadstack71; + public Int64 maxuse_threadstack72; + public Int64 maxuse_threadstack73; + public Int64 maxuse_threadstack74; + public Int64 maxuse_threadstack75; + public Int64 maxuse_threadstack76; + public Int64 maxuse_threadstack77; + public Int64 maxuse_threadstack78; + public Int64 maxuse_threadstack79; + public Int64 maxuse_threadstack80; + public Int64 maxuse_threadstack81; + public Int64 maxuse_threadstack82; + public Int64 maxuse_threadstack83; + public Int64 maxuse_threadstack84; + public Int64 maxuse_threadstack85; + public Int64 maxuse_threadstack86; + public Int64 maxuse_threadstack87; + public Int64 maxuse_threadstack88; + public Int64 maxuse_threadstack89; + public Int64 maxuse_threadstack90; + public Int64 maxuse_threadstack91; + public Int64 maxuse_threadstack92; + public Int64 maxuse_threadstack93; + public Int64 maxuse_threadstack94; + public Int64 maxuse_threadstack95; + public Int64 maxuse_threadstack96; + public Int64 maxuse_threadstack97; + public Int64 maxuse_threadstack98; + public Int64 maxuse_threadstack99; + public Int64 maxuse_threadstack100; + public Int64 maxuse_threadstack101; + public Int64 maxuse_threadstack102; + public Int64 maxuse_threadstack103; + public Int64 maxuse_threadstack104; + public Int64 maxuse_threadstack105; + public Int64 maxuse_threadstack106; + public Int64 maxuse_threadstack107; + public Int64 maxuse_threadstack108; + public Int64 maxuse_threadstack109; + public Int64 maxuse_threadstack110; + public Int64 maxuse_threadstack111; + public Int64 maxuse_threadstack112; + public Int64 maxuse_threadstack113; + public Int64 maxuse_threadstack114; + public Int64 maxuse_threadstack115; + public Int64 maxuse_threadstack116; + public Int64 maxuse_threadstack117; + public Int64 maxuse_threadstack118; + public Int64 maxuse_threadstack119; + public Int64 maxuse_threadstack120; + public Int64 maxuse_threadstack121; + public Int64 maxuse_threadstack122; + public Int64 maxuse_threadstack123; + public Int64 maxuse_threadstack124; + public Int64 maxuse_threadstack125; + public Int64 maxuse_threadstack126; + public Int64 maxuse_threadstack127; + public Int64 maxuse_arena; public int maxuse_con; public int maxuse_efc; public mjSolverStat_ solver0; @@ -5349,8 +5349,8 @@ public unsafe struct mjModel_ { public int nuserdata; public int nsensordata; public int npluginstate; - public UInt64 narena; - public UInt64 nbuffer; + public Int64 narena; + public Int64 nbuffer; public mjOption_ opt; public mjVisual_ vis; public mjStatistic_ stat; @@ -6448,7 +6448,7 @@ public static unsafe extern mjModel_* mj_loadModel([MarshalAs(UnmanagedType.LPSt public static unsafe extern void mj_deleteModel(mjModel_* m); [DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)] -public static unsafe extern UInt64 mj_sizeModel(mjModel_* m); +public static unsafe extern Int64 mj_sizeModel(mjModel_* m); [DllImport("mujoco", CallingConvention = CallingConvention.Cdecl)] public static unsafe extern mjData_* mj_makeData(mjModel_* m);