git: 6c57e368eb17 - main - lib/libc: implement C23 memalignment()
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 12 Nov 2025 12:24:49 UTC
The branch main has been updated by fuz:
URL: https://cgit.FreeBSD.org/src/commit/?id=6c57e368eb1777f6097158eeca2fcc175d068dba
commit 6c57e368eb1777f6097158eeca2fcc175d068dba
Author: Robert Clausecker <fuz@FreeBSD.org>
AuthorDate: 2025-11-10 17:54:41 +0000
Commit: Robert Clausecker <fuz@FreeBSD.org>
CommitDate: 2025-11-12 12:23:09 +0000
lib/libc: implement C23 memalignment()
This new function computes the alignment of a pointer.
It is part of ISO/IEC 9899:2024, the new C standard.
If the pointer is a null pointer, null is returned.
I have tried to write an implementation that can cope
with traditional address-based architectures, even if
size_t and uintptr_t are of different length. Adjustments
may be needed for CHERI though.
A man page is provided, too. No unit test for now.
Reviewed by: kib, imp, ziaee (manpages), pauamma@gundo.com
Approved by: markj (mentor)
MFC after: 1 month
Relnotes: yes
Differential Revision: https://reviews.freebsd.org/D53673
---
include/stdlib.h | 8 +++++++
lib/libc/stdlib/Makefile.inc | 4 ++--
lib/libc/stdlib/Symbol.map | 1 +
lib/libc/stdlib/memalignment.3 | 53 ++++++++++++++++++++++++++++++++++++++++++
lib/libc/stdlib/memalignment.c | 28 ++++++++++++++++++++++
5 files changed, 92 insertions(+), 2 deletions(-)
diff --git a/include/stdlib.h b/include/stdlib.h
index 784cb63bfc5b..3e54b5feb6de 100644
--- a/include/stdlib.h
+++ b/include/stdlib.h
@@ -167,6 +167,14 @@ int at_quick_exit(void (*)(void)) __noexcept;
_Noreturn void
quick_exit(int) /* __noexcept -- not ready ABI issues? */;
#endif /* __ISO_C_VISIBLE >= 2011 */
+
+/*
+ * C23 extensions
+ */
+#if __ISO_C_VISIBLE >= 2023
+size_t memalignment(const void *) __pure2;
+#endif /* __ISO_C_VISIBLE >= 2023 */
+
/*
* Extensions made by POSIX relative to C.
*/
diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc
index e7b9955b9646..b878a7625e9f 100644
--- a/lib/libc/stdlib/Makefile.inc
+++ b/lib/libc/stdlib/Makefile.inc
@@ -7,7 +7,7 @@ MISRCS+=C99_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \
div.c exit.c getenv.c getopt.c getopt_long.c \
getsubopt.c hcreate.c hcreate_r.c hdestroy_r.c heapsort.c heapsort_b.c \
hsearch_r.c imaxabs.c imaxdiv.c \
- insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \
+ insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c memalignment.c \
merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c qsort_r_compat.c \
qsort_s.c quick_exit.c radixsort.c rand.c \
random.c reallocarray.c reallocf.c realpath.c recallocarray.c remque.c \
@@ -35,7 +35,7 @@ MAN+= a64l.3 abort.3 abs.3 atexit.3 atof.3 \
atoi.3 atol.3 at_quick_exit.3 bsearch.3 \
div.3 exit.3 getenv.3 getopt.3 getopt_long.3 getsubopt.3 \
hcreate.3 imaxabs.3 imaxdiv.3 insque.3 labs.3 ldiv.3 llabs.3 lldiv.3 \
- lsearch.3 memory.3 ptsname.3 qsort.3 \
+ lsearch.3 memalignment.3 memory.3 ptsname.3 qsort.3 \
quick_exit.3 \
radixsort.3 rand.3 random.3 reallocarray.3 reallocf.3 realpath.3 \
set_constraint_handler_s.3 \
diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map
index 53d71bcafb7d..8b7e97c3cbdc 100644
--- a/lib/libc/stdlib/Symbol.map
+++ b/lib/libc/stdlib/Symbol.map
@@ -132,6 +132,7 @@ FBSD_1.8 {
};
FBSD_1.9 {
+ memalignment;
recallocarray;
};
diff --git a/lib/libc/stdlib/memalignment.3 b/lib/libc/stdlib/memalignment.3
new file mode 100644
index 000000000000..4a2269a82c81
--- /dev/null
+++ b/lib/libc/stdlib/memalignment.3
@@ -0,0 +1,53 @@
+.\"
+.\" Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+.\"
+.\" SPDX-License-Identifier: BSD-2-Clause
+.\"
+.Dd November 10, 2025
+.Dt MEMALIGNMENT 3
+.Os
+.Sh NAME
+.Nm memalignment
+.Nd find the memory alignment of an object
+.Sh SYNOPSIS
+.Lb libc
+.In stdlib.h
+.Ft size_t
+.Fn memalignment "const void *ptr"
+.Sh DESCRIPTION
+The
+.Fn memalignment
+function determines the alignment of the object pointed to by
+.Fa ptr .
+This alignment is a power of\~2, and may be larger than the range
+supported by the
+.Sy alignof
+operator.
+The value returned can be compared to the result of
+.Sy alignof ,
+and if it is greater or equal, the alignment requirement of the operand
+is satisfied.
+.Sh RETURN VALUES
+Returns the alignment of
+.Fa ptr
+as a power of\~2.
+If
+.Fa ptr
+is a null pointer, an alignment of zero is returned.
+An alignment of zero indicates that the tested pointer cannot be used to
+access an object of any type.
+.Sh SEE ALSO
+.Xr aligned_alloc 3 ,
+.Xr posix_memalign 3
+.Sh STANDARDS
+The
+.Fn memalignment
+function conforms to
+.St -isoC-2023 .
+.Sh HISTORY
+The
+.Fn memalignment
+function was added in
+.Fx 15.1.
+.Sh AUTHOR
+.An Robert Clausecker Aq Mt fuz@FreeBSD.org
diff --git a/lib/libc/stdlib/memalignment.c b/lib/libc/stdlib/memalignment.c
new file mode 100644
index 000000000000..771ddc2f5253
--- /dev/null
+++ b/lib/libc/stdlib/memalignment.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2025 Robert Clausecker <fuz@FreeBSD.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+size_t
+memalignment(const void *p)
+{
+ uintptr_t align;
+
+ if (p == NULL)
+ return (0);
+
+ align = (uintptr_t)p;
+ align &= -align;
+
+#if UINTPTR_MAX > SIZE_MAX
+ /* if alignment overflows size_t, return maximum possible */
+ if (align > SIZE_MAX)
+ align = SIZE_MAX - SIZE_MAX/2;
+#endif
+
+ return (align);
+}