summaryrefslogtreecommitdiff
path: root/manual
diff options
context:
space:
mode:
authorJoseph Myers <josmyers@redhat.com>2025-10-17 16:56:59 +0000
committerJoseph Myers <josmyers@redhat.com>2025-10-17 16:56:59 +0000
commitea18d5a4c2583726060326b8a348de0845c22aa1 (patch)
treed38f265bdd03061704a6f8294c4a315c8c72d780 /manual
parent850d93f514ebc3c8b62603e70586edd38a18f46b (diff)
Implement C23 memalignment
Add the C23 memalignment function (query the alignment of a pointer) to glibc. Given how simple this operation is, it would make sense for compilers to inline calls to this function, but I'm treating that as a compiler matter (compilers should add it as a built-in function) rather than adding an inline version to glibc headers (although such an inline version would be reasonable as well). I've filed https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122117 for this feature in GCC. Tested for x86_64 and x86.
Diffstat (limited to 'manual')
-rw-r--r--manual/memory.texi55
1 files changed, 55 insertions, 0 deletions
diff --git a/manual/memory.texi b/manual/memory.texi
index 6a70168e61..dd6c7f9996 100644
--- a/manual/memory.texi
+++ b/manual/memory.texi
@@ -1135,6 +1135,61 @@ The @code{valloc} function is obsolete and @code{aligned_alloc} or
@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