* The ISO C23 memset_explicit function has been added.
+* The ISO C23 memalignment function has been added.
+
Deprecated and removed features, and other changes affecting compatibility:
* Support for dumped heaps has been removed - malloc_set_state() now always
@code{posix_memalign} should be used instead.
@end deftypefun
+You can determine the alignment of a pointer with the
+@code{memalignment} function.
+
+@deftypefun size_t memalignment (void *@var{p})
+@standards{C23, stdlib.h}
+@safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
+
+This function, defined in C23, returns the alignment of @var{p}, as a
+power of two. If @var{p} is a null pointer, it returns zero. C23
+requires @var{p} to be a valid pointer to an object or a null pointer;
+as a GNU extension, @theglibc{} supports this function on arbitrary
+bit patterns of pointer type.
+
+This function was added to the C23 standard to support unconventional
+platforms where a pointer's low-order bits are unrelated to alignment.
+For conventional platforms, one can instead cast the pointer to
+@code{uintptr_t} and then test the low order bits:
+this is portable to pre-C23 and is typically a bit faster.
+
+For example, if you want to read an @code{int}
+addressed by possibly-misaligned pointer @code{p},
+the following pre-C23 code works on all conventional platforms:
+
+@smallexample
+int i;
+if (((uintptr_t) p & (alignof (int) - 1)) != 0)
+ memcpy (&i, p, sizeof i);
+else
+ i = *p;
+@end smallexample
+
+However, it might not work on unconventional platforms, where one
+would need something like the following C23 code:
+
+@smallexample
+int i;
+if (memalignment (p) < alignof (int))
+ memcpy (&i, p, sizeof i);
+else
+ i = *p;
+@end smallexample
+
+However, for this particular case, performance does not improve if
+different code is used for aligned and unaligned pointers,
+and the following code is preferable:
+
+@smallexample
+int i;
+memcpy (&i, p, sizeof i);
+@end smallexample
+
+The compiler will generate the most efficient way to access unaligned
+data for the architecture, optimizing away the @code{memcpy} call.
+@end deftypefun
+
@node Malloc Tunable Parameters
@subsubsection Malloc Tunable Parameters
mblen \
mbstowcs \
mbtowc \
+ memalignment \
mrand48 \
mrand48_r \
nrand48 \
tst-makecontext-align \
tst-makecontext2 \
tst-makecontext3 \
+ tst-memalignment \
tst-on_exit \
tst-qsort \
tst-qsort2 \
CFLAGS-tst-stdc_bit_floor.c += -fno-builtin
CFLAGS-tst-stdc_bit_ceil.c += -fno-builtin
+CFLAGS-tst-memalignment.c += -fno-builtin
+
ifeq ($(have-cxx-thread_local),yes)
CFLAGS-tst-quick_exit.o = -std=c++11
LDLIBS-tst-quick_exit = -lstdc++
ulabs;
ullabs;
}
+ GLIBC_2.43 {
+ memalignment;
+ }
GLIBC_PRIVATE {
# functions which have an additional interface since they are
# are cancelable.
--- /dev/null
+/* Return the alignment of a pointer.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+
+/* Return the alignment of P. */
+size_t
+memalignment (const void *p)
+{
+ size_t i = (size_t) p;
+ return i & -i;
+}
/* Call function __FUNC exactly once, even if invoked from several threads.
All calls must be made with the same __FLAGS object. */
extern void call_once (once_flag *__flag, void (*__func)(void));
+
+/* Return the alignment of P. */
+extern size_t memalignment (const void *__p);
#endif
#include <bits/stdlib-float.h>
--- /dev/null
+/* Test memalignment.
+ Copyright (C) 2025 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <array_length.h>
+#include <support/check.h>
+
+static int
+do_test (void)
+{
+ void *null = NULL;
+ TEST_COMPARE (memalignment (NULL), 0);
+ TEST_COMPARE (memalignment (null), 0);
+ char ca[256];
+ array_foreach (p, ca)
+ TEST_VERIFY (memalignment (p) >= 1);
+ TEST_VERIFY (memalignment (&ca[0]) == 1 || memalignment (&ca[1]) == 1);
+ TEST_VERIFY (memalignment (&ca[0]) == 2 || memalignment (&ca[1]) == 2
+ || memalignment (&ca[2]) == 2 || memalignment (&ca[3]) == 2);
+ long long int lla[256];
+ array_foreach (p, lla)
+ TEST_VERIFY (memalignment (p) >= _Alignof (long long int));
+ TEST_VERIFY (memalignment (&lla[0]) <= sizeof (long long int)
+ || memalignment (&lla[1]) <= sizeof (long long int));
+ return 0;
+}
+
+#include <support/test-driver.c>
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.43 pthread_cancel F
GLIBC_2.43 pthread_clockjoin_np F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.43 pthread_cancel F
GLIBC_2.43 pthread_clockjoin_np F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F
GLIBC_2.5 __readlinkat_chk F
GLIBC_2.5 inet6_opt_append F
GLIBC_2.42 ulabs F
GLIBC_2.42 ullabs F
GLIBC_2.43 __memset_explicit_chk F
+GLIBC_2.43 memalignment F
GLIBC_2.43 memset_explicit F