* [PATCH 1/3] move more limits from kernel.h to limits.h and standardize their definitions
2025-07-03 11:37 [PATCH 0/3] integer limit macro consolidation Rasmus Villemoes
@ 2025-07-03 11:37 ` Rasmus Villemoes
2025-07-03 11:37 ` [PATCH 2/3] move limits for sNN/uNN types from kernel.h to limits.h Rasmus Villemoes
` (2 subsequent siblings)
3 siblings, 0 replies; 6+ messages in thread
From: Rasmus Villemoes @ 2025-07-03 11:37 UTC (permalink / raw)
To: u-boot; +Cc: Tom Rini, Rasmus Villemoes
In a customer project that was building a stand-alone application, I
hit a problem related to the fact that our LONG_MAX and friends are
not standards-compliant, in that they are not "suitable for use in #if
preprocessing directives"
... /toolchain_none/arm-cortexa8-eabi/sys-include/machine/_default_types.h:25:31: error: missing binary operator before token "long"
25 | || ( defined(LLONG_MAX) && (LLONG_MAX > 0x7fffffff) )
| ^~~~~~~~~
So following up on commit 13de8483388 ("mbedtls: add mbedtls into the
build system"), move the rest of the macros associated to the standard
C types {signed,unsigned} {char, short, int, long, long long} (and of
course bare 'char') to limits.h.
Make use of the fact that both gcc and clang provide suitable
predefined __FOO_MAX__ macros for the signed types, and use a standard
scheme for defining the FOO_MIN and UFOO_MAX macros in terms of
FOO_MAX.
Note that suffixes like L and ULL are allowed for preprocessor
integers; it is (casts) which are not. And using appropriate suffixes,
we can arrange for the type of e.g. UINT_MAX to be "unsigned int" due
to integer promotion rules.
Signed-off-by: Rasmus Villemoes <ravi@prevas.dk>
---
include/limits.h | 30 ++++++++++++++++++++++++++++--
include/linux/kernel.h | 11 -----------
2 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/include/limits.h b/include/limits.h
index 1d0bbf69be7..ec111023e00 100644
--- a/include/limits.h
+++ b/include/limits.h
@@ -3,8 +3,34 @@
#ifndef _LIMITS_H
#define _LIMITS_H
-#define INT_MAX 0x7fffffff
-#define UINT_MAX 0xffffffffU
+#define SCHAR_MAX __SCHAR_MAX__
+#define SCHAR_MIN (-SCHAR_MAX - 1)
+#define UCHAR_MAX (SCHAR_MAX * 2 + 1)
+
+#ifdef __CHAR_UNSIGNED__
+#define CHAR_MAX UCHAR_MAX
+#define CHAR_MIN 0
+#else
+#define CHAR_MAX SCHAR_MAX
+#define CHAR_MIN SCHAR_MIN
+#endif
+
+#define SHRT_MAX __SHRT_MAX__
+#define SHRT_MIN (-SHRT_MAX - 1)
+#define USHRT_MAX (SHRT_MAX * 2 + 1)
+
+#define INT_MAX __INT_MAX__
+#define INT_MIN (-INT_MAX - 1)
+#define UINT_MAX (INT_MAX * 2U + 1U)
+
+#define LONG_MAX __LONG_MAX__
+#define LONG_MIN (-LONG_MAX - 1L)
+#define ULONG_MAX (LONG_MAX * 2UL + 1UL)
+
+#define LLONG_MAX __LONG_LONG_MAX__
+#define LLONG_MIN (-LONG_LONG_MAX - 1LL)
+#define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
+
#define CHAR_BIT 8
#define UINT32_MAX 0xffffffffU
#define UINT64_MAX 0xffffffffffffffffULL
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index 9467edd65ab..f26274fbe1d 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -5,17 +5,6 @@
#include <linux/printk.h> /* for printf/pr_* utilities */
#include <limits.h>
-#define USHRT_MAX ((u16)(~0U))
-#define SHRT_MAX ((s16)(USHRT_MAX>>1))
-#define SHRT_MIN ((s16)(-SHRT_MAX - 1))
-#define INT_MIN (-INT_MAX - 1)
-#define LONG_MAX ((long)(~0UL>>1))
-#define LONG_MIN (-LONG_MAX - 1)
-#define ULONG_MAX (~0UL)
-#define LLONG_MAX ((long long)(~0ULL>>1))
-#define LLONG_MIN (-LLONG_MAX - 1)
-#define ULLONG_MAX (~0ULL)
-
#define U8_MAX ((u8)~0U)
#define S8_MAX ((s8)(U8_MAX>>1))
#define S8_MIN ((s8)(-S8_MAX - 1))
--
2.50.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 2/3] move limits for sNN/uNN types from kernel.h to limits.h
2025-07-03 11:37 [PATCH 0/3] integer limit macro consolidation Rasmus Villemoes
2025-07-03 11:37 ` [PATCH 1/3] move more limits from kernel.h to limits.h and standardize their definitions Rasmus Villemoes
@ 2025-07-03 11:37 ` Rasmus Villemoes
2025-07-03 11:37 ` [PATCH 3/3] limits.h: provide all limit macros for standard [u]intNN_t types Rasmus Villemoes
2025-07-04 22:10 ` [PATCH 0/3] integer limit macro consolidation Tom Rini
3 siblings, 0 replies; 6+ messages in thread
From: Rasmus Villemoes @ 2025-07-03 11:37 UTC (permalink / raw)
To: u-boot; +Cc: Tom Rini, Rasmus Villemoes
Since we define the {s,u}{8,16,32,64} types the same way on all
architectures, i.e. everybody uses asm-generic/int-ll64.h, we can just
define the associated limit macros in terms of those for the
corresponding types. This eliminates another set of limit macros that
are not usable in #if conditionals.
These type names and macros are not C or POSIX, so there's no language
violation, but certainly a violation of developers' reasonable
expectations.
Signed-off-by: Rasmus Villemoes <ravi@prevas.dk>
---
include/limits.h | 13 +++++++++++++
include/linux/kernel.h | 13 -------------
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/include/limits.h b/include/limits.h
index ec111023e00..aa30f5dc8d8 100644
--- a/include/limits.h
+++ b/include/limits.h
@@ -31,6 +31,19 @@
#define LLONG_MIN (-LONG_LONG_MAX - 1LL)
#define ULLONG_MAX (LLONG_MAX * 2ULL + 1ULL)
+#define U8_MAX UCHAR_MAX
+#define S8_MAX SCHAR_MAX
+#define S8_MIN SCHAR_MIN
+#define U16_MAX USHRT_MAX
+#define S16_MAX SHRT_MAX
+#define S16_MIN SHRT_MIN
+#define U32_MAX UINT_MAX
+#define S32_MAX INT_MAX
+#define S32_MIN INT_MIN
+#define U64_MAX ULLONG_MAX
+#define S64_MAX LLONG_MAX
+#define S64_MIN LLONG_MIN
+
#define CHAR_BIT 8
#define UINT32_MAX 0xffffffffU
#define UINT64_MAX 0xffffffffffffffffULL
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f26274fbe1d..d3d979834ae 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -5,19 +5,6 @@
#include <linux/printk.h> /* for printf/pr_* utilities */
#include <limits.h>
-#define U8_MAX ((u8)~0U)
-#define S8_MAX ((s8)(U8_MAX>>1))
-#define S8_MIN ((s8)(-S8_MAX - 1))
-#define U16_MAX ((u16)~0U)
-#define S16_MAX ((s16)(U16_MAX>>1))
-#define S16_MIN ((s16)(-S16_MAX - 1))
-#define U32_MAX ((u32)~0U)
-#define S32_MAX ((s32)(U32_MAX>>1))
-#define S32_MIN ((s32)(-S32_MAX - 1))
-#define U64_MAX ((u64)~0ULL)
-#define S64_MAX ((s64)(U64_MAX>>1))
-#define S64_MIN ((s64)(-S64_MAX - 1))
-
#define INT32_MAX S32_MAX
#define STACK_MAGIC 0xdeadbeef
--
2.50.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* [PATCH 3/3] limits.h: provide all limit macros for standard [u]intNN_t types
2025-07-03 11:37 [PATCH 0/3] integer limit macro consolidation Rasmus Villemoes
2025-07-03 11:37 ` [PATCH 1/3] move more limits from kernel.h to limits.h and standardize their definitions Rasmus Villemoes
2025-07-03 11:37 ` [PATCH 2/3] move limits for sNN/uNN types from kernel.h to limits.h Rasmus Villemoes
@ 2025-07-03 11:37 ` Rasmus Villemoes
2025-07-04 22:10 ` [PATCH 0/3] integer limit macro consolidation Tom Rini
3 siblings, 0 replies; 6+ messages in thread
From: Rasmus Villemoes @ 2025-07-03 11:37 UTC (permalink / raw)
To: u-boot; +Cc: Tom Rini, Rasmus Villemoes
Currently, we only have UINT32_MAX and UINT64_MAX in limits.h, and
then stdint.h and kernel.h somewhat randomly define UINT8_MAX and
INT32_MAX, respectively.
Provide a full set of definitions in terms of the min/max macros for
the types that [u]intNN_t are defined in terms of, namely the {s,u}NN
ones.
Try to avoid breaking whatever depended on getting UINT8_MAX from our
compat stdint.h by replacing it with an include of limits.h.
Signed-off-by: Rasmus Villemoes <ravi@prevas.dk>
---
include/limits.h | 15 +++++++++++++--
include/linux/kernel.h | 2 --
include/stdint.h | 2 +-
3 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/include/limits.h b/include/limits.h
index aa30f5dc8d8..57640a1c6d4 100644
--- a/include/limits.h
+++ b/include/limits.h
@@ -44,9 +44,20 @@
#define S64_MAX LLONG_MAX
#define S64_MIN LLONG_MIN
+#define UINT8_MAX U8_MAX
+#define INT8_MAX S8_MAX
+#define INT8_MIN S8_MIN
+#define UINT16_MAX U16_MAX
+#define INT16_MAX S16_MAX
+#define INT16_MIN S16_MIN
+#define UINT32_MAX U32_MAX
+#define INT32_MAX S32_MAX
+#define INT32_MIN S32_MIN
+#define UINT64_MAX U64_MAX
+#define INT64_MAX S64_MAX
+#define INT64_MIN S64_MIN
+
#define CHAR_BIT 8
-#define UINT32_MAX 0xffffffffU
-#define UINT64_MAX 0xffffffffffffffffULL
#if (defined(CONFIG_64BIT) && !defined(CONFIG_SPL_BUILD)) || \
(defined(CONFIG_SPL_64BIT) && defined(CONFIG_SPL_BUILD))
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index d3d979834ae..e0443ecac84 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -5,8 +5,6 @@
#include <linux/printk.h> /* for printf/pr_* utilities */
#include <limits.h>
-#define INT32_MAX S32_MAX
-
#define STACK_MAGIC 0xdeadbeef
#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x))
diff --git a/include/stdint.h b/include/stdint.h
index dea83c8226a..90fd2bdee08 100644
--- a/include/stdint.h
+++ b/include/stdint.h
@@ -9,6 +9,6 @@
#ifndef __UB_STDINT_H
#define __UB_STDINT_H
-#define UINT8_MAX 0xff
+#include <limits.h>
#endif
--
2.50.0
^ permalink raw reply related [flat|nested] 6+ messages in thread* Re: [PATCH 0/3] integer limit macro consolidation
2025-07-03 11:37 [PATCH 0/3] integer limit macro consolidation Rasmus Villemoes
` (2 preceding siblings ...)
2025-07-03 11:37 ` [PATCH 3/3] limits.h: provide all limit macros for standard [u]intNN_t types Rasmus Villemoes
@ 2025-07-04 22:10 ` Tom Rini
2025-07-07 20:39 ` Rasmus Villemoes
3 siblings, 1 reply; 6+ messages in thread
From: Tom Rini @ 2025-07-04 22:10 UTC (permalink / raw)
To: Rasmus Villemoes; +Cc: u-boot
[-- Attachment #1: Type: text/plain, Size: 1244 bytes --]
On Thu, Jul 03, 2025 at 01:37:27PM +0200, Rasmus Villemoes wrote:
> I was bitten by our limit macros not being usable in #if conditionals
> when building a standalone app. It turns out that the work to fix that
> had already been started by the inclusion of the mbedtls library, so
> it's something that people do hit.
>
> Let's finish the job by providing suitable limit macros for all three families:
>
> - Standard C types, char, short, ...
> - Kernel-style fixed-width types s8, u64, ...
> - POSIX/C99 fixed-width types int16_t, uint32_t, ...
>
> Please note that a naive approach like spelling out the full decimal
> value for the constants doesn't really work, as there is no such thing
> as a "negative integer constant". That is, doing
>
> #define LLONG_MIN -9223372036854775808LL
>
> would lead to the compiler complaining
>
> warning: integer constant is so large that it is unsigned
>
> and the type of that LLONG_MIN would actually be "unsigned long long", so e.g.
>
> #if LLONG_MIN >= 0
> #warning "LLONG_MIN is not negative?"
> #endif
>
> would fire.
Thanks for doing this. I assume you put this through CI? My only real
concern there is with host tools on macOS/Windows.
--
Tom
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread* Re: [PATCH 0/3] integer limit macro consolidation
2025-07-04 22:10 ` [PATCH 0/3] integer limit macro consolidation Tom Rini
@ 2025-07-07 20:39 ` Rasmus Villemoes
0 siblings, 0 replies; 6+ messages in thread
From: Rasmus Villemoes @ 2025-07-07 20:39 UTC (permalink / raw)
To: Tom Rini; +Cc: u-boot
On Fri, Jul 04 2025, Tom Rini <trini@konsulko.com> wrote:
> On Thu, Jul 03, 2025 at 01:37:27PM +0200, Rasmus Villemoes wrote:
>
>> I was bitten by our limit macros not being usable in #if conditionals
>> when building a standalone app. It turns out that the work to fix that
>> had already been started by the inclusion of the mbedtls library, so
>> it's something that people do hit.
>>
>> Let's finish the job by providing suitable limit macros for all three families:
>>
>> - Standard C types, char, short, ...
>> - Kernel-style fixed-width types s8, u64, ...
>> - POSIX/C99 fixed-width types int16_t, uint32_t, ...
>>
>
> Thanks for doing this. I assume you put this through CI?
I wanted to, forgot to actually do it. But now I have, and it found a
thinko/typo in 1/3. Fixed that up and now CI is happy, so just sent v2.
Thanks,
Rasmus
^ permalink raw reply [flat|nested] 6+ messages in thread