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
This commit is contained in:
Robert Clausecker 2025-11-10 12:54:41 -05:00
parent 4ab2d625e1
commit 6c57e368eb
5 changed files with 92 additions and 2 deletions

View file

@ -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.
*/

View file

@ -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 \

View file

@ -132,6 +132,7 @@ FBSD_1.8 {
};
FBSD_1.9 {
memalignment;
recallocarray;
};

View file

@ -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

View file

@ -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);
}