在 2026-2-25 10:11, David Grayson 写道:
I'm doing this because I tried to compile some native Windows software that
referred to DWORD_MAX, and it failed because that macro was missing in
intsafe.h .

 From 1a314f9326576773b4869220479291a3f8df6aab Mon Sep 17 00:00:00 2001
From: David Grayson <[email protected]>
Date: Tue, 24 Feb 2026 17:33:41 -0800
Subject: [PATCH] headers/intsafe: Add missing MIN/MAX macros.

I tested this with my test suite at
https://github.com/DavidEGrayson/intsafe
to make sure the values and types are correct in
32-bit/64-bit MinGW and 64-bit Cygwin environments.

Potential compatibility issues:
- The types of smaller macros like UINT8_MAX are 'int',
   which is different from Microsoft's intsafe.h, but follows the
   C specification and allows the preprocessor to understand
   the macro's numeric value.
- LONG_MIN, LONG_MAX, and ULONG_MAX describe 'long' and 'unsigned long',
   whereas native Windows code might expect them to describe
   LONG and ULONG, which sometimes have a different size.
- Some of these definitions are different than what we have in
   stdint.h, limits.h, and cfgmgr32.h, so I'd like to submit a patch
   for those later if this is accepted.

To keep things consistent and simple, I followed these rules:
- A macro does not refer to another macro unless it saves a line of code.
   Chains of macros are hard to debug because other included headers
   could break the chain by redefining any macro in the chain.
- Only use decimal if it makes the number shorter (otherwise use hex).
- Don't use uppercase hex digits.
- Only use suffixes if necessary.  But use an explicit "u" on any
   unsigned literal that has a suffix.

This doesn't seem to be consistently maintained; see below.


- Don't use uppercase suffixes (for compatibility with __MSABI_LONG).
- Only use subtraction if necessary.

Signed-off-by: David Grayson <[email protected]>
---
  mingw-w64-headers/include/intsafe.h | 66 +++++++++++++++++++++++++++++
  1 file changed, 66 insertions(+)

diff --git a/mingw-w64-headers/include/intsafe.h
b/mingw-w64-headers/include/intsafe.h
index 17f3bda1e..f04765e45 100644
--- a/mingw-w64-headers/include/intsafe.h
+++ b/mingw-w64-headers/include/intsafe.h
@@ -14,6 +14,72 @@
  #include <wtypesbase.h>
  #include <specstrings.h>

+#define INT8_MIN (-128)
+#define INT8_MAX 127
+#define UINT8_MAX 255
+#define BYTE_MAX 255
+#define INT16_MIN (-32768)
+#define INT16_MAX 32767
+#define SHORT_MIN (-32768)
+#define SHORT_MAX 32767
+#define UINT16_MAX 65535
+#define USHORT_MAX 65535
+#define WORD_MAX 65535
+#define INT32_MIN (-0x7fffffff - 1)
+#define INT32_MAX 0x7fffffff
+#define INT_MIN (-0x7fffffff - 1)
+#define INT_MAX 0x7fffffff
+#define UINT32_MAX 0xffffffff
+#define UINT_MAX 0xffffffff

... why no `u` here?


+#define DWORD_MAX __MSABI_LONG(0xffffffffu)
+#define INT64_MIN (-0x7fffffffffffffff - 1)
+#define INT64_MAX 0x7fffffffffffffff
+#define LONGLONG_MIN (-0x7fffffffffffffffll - 1)
+#define LONG64_MIN (-0x7fffffffffffffffll - 1)
+#define LONGLONG_MAX 0x7fffffffffffffffll
+#define LONG64_MAX 0x7fffffffffffffffll
+#define UINT64_MAX 0xffffffffffffffff
+#define ULONGLONG_MAX 0xffffffffffffffffull
+#define ULONG64_MAX 0xffffffffffffffffull
+#define DWORDLONG_MAX 0xffffffffffffffffull
+#define DWORD64_MAX 0xffffffffffffffffull
+
+#ifdef __LP64__
+#define LONG_MIN (-0x7fffffffffffffff - 1)
+#define LONG_MAX 0x7fffffffffffffff
+#define ULONG_MAX 0xffffffffffffffff

And why no `l` here?


+#else
+#define LONG_MIN (-0x7fffffffl - 1)
+#define LONG_MAX 0x7fffffffl
+#define ULONG_MAX 0xfffffffful
+#endif
+
+#ifdef _WIN64

I think this should be `#if defined _WIN64 || defined _LP64`, as Cygwin/MSYS2 
never defines `_WIN64`.


+#define PTRDIFF_T_MIN (-0x7fffffffffffffff - 1)
+#define PTRDIFF_T_MAX 0x7fffffffffffffff
+#define SIZE_T_MAX 0xffffffffffffffff

Still no `u` here?


+#define INT_PTR_MIN (-0x7fffffffffffffffll - 1)
+#define INT_PTR_MAX 0x7fffffffffffffffll
+#define UINT_PTR_MAX 0xffffffffffffffffull
+#define LONG_PTR_MIN (-0x7fffffffffffffffll - 1)
+#define LONG_PTR_MAX 0x7fffffffffffffffll
+#define ULONG_PTR_MAX 0xffffffffffffffffull
+#else
+#define PTRDIFF_T_MIN (-0x7fffffff - 1)
+#define PTRDIFF_T_MAX 0x7fffffff
+#define SIZE_T_MAX 0xffffffff

On 32-bit targets, `SIZE_T` is `unsigned long` but `size_t is `unsigned int`, so in Microsoft headers, they have

 - `SIZE_T_MAX` is the maximum value of `size_t` which is `0xffffffff`, and
 - `_SIZE_T_MAX` is the maximum value of `SIZE_T` which is `0xffffffffUL`, and
 - `SSIZE_T_MAX` is the maximum value of `SSIZE_T` which is `2147483647L`.

The fact that `SIZE_T_MAX` is defined inconsistently is probably a mistake, so 
they need `_SIZE_T_MAX`.


+#define INT_PTR_MIN (-0x7fffffff - 1)
+#define INT_PTR_MAX 0x7fffffff
+#define UINT_PTR_MAX 0xffffffff

Yet this needs `u`.


+#define LONG_PTR_MIN (-0x7fffffffl - 1)
+#define LONG_PTR_MAX 0x7fffffffl
+#define ULONG_PTR_MAX 0xfffffffful
+#endif
+#define SSIZE_T_MIN LONG_PTR_MIN
+#define SSIZE_T_MAX LONG_PTR_MAX
+#define _SIZE_T_MAX ULONG_PTR_MAX
+#define DWORD_PTR_MAX ULONG_PTR_MAX
+
  #define INTSAFE_E_ARITHMETIC_OVERFLOW ((HRESULT)0x80070216)

  #ifndef S_OK
--
2.52.0



_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public


--
Best regards,
LIU Hao

Attachment: OpenPGP_signature.asc
Description: OpenPGP digital signature

_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to