diff --git a/include/stdlib.h b/include/stdlib.h --- a/include/stdlib.h +++ b/include/stdlib.h @@ -167,6 +167,14 @@ _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 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -7,7 +7,7 @@ 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 @@ 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 --- a/lib/libc/stdlib/Symbol.map +++ b/lib/libc/stdlib/Symbol.map @@ -132,6 +132,7 @@ }; FBSD_1.9 { + memalignment; recallocarray; }; diff --git a/lib/libc/stdlib/memalignment.3 b/lib/libc/stdlib/memalignment.3 new file mode 100644 --- /dev/null +++ b/lib/libc/stdlib/memalignment.3 @@ -0,0 +1,53 @@ +.\"- +.\" Copyright (c) 2025 Robert Clausecker +.\" +.\" 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 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 --- /dev/null +++ b/lib/libc/stdlib/memalignment.c @@ -0,0 +1,28 @@ +/*- + * Copyright (c) 2025 Robert Clausecker + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include +#include + +size_t +memalignment(const void *p) +{ + uintptr_t align; + + if (p == NULL) + return (0); + + align = (uintptr_t)p; + align &= align - 1; + +#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); +}