Re: [PATCH v1 00/12] man/man3/posix_memalign.3: Several fixes, and split the page
From: Alejandro Colomar <alx@kernel.org>
Date: 2025-12-11 00:04:29
[CC += Ingo] Hi Eugene, Ingo, On Wed, Dec 10, 2025 at 11:50:33PM +0100, Eugene Syromyatnikov wrote:
On Wed, Dec 10, 2025 at 6:12 PM Alejandro Colomar [off-list ref] wrote:
[...]
quoted
posix_memalign(3) is terrible, because it takes a void**, which requires a cast. memalign(3) is okay, except that it need not report invalid alignments.quoted
and due to its limitation of size being multiple of alignment, that renders it useless for the vast majority of use cases.That limitation doesn't exist. It was a bug in C11. Both musl and glibc seem okay: alx@devuan:~$ grepc -tfd aligned_alloc ~/src/gnu/glibc/master/ /home/alx/src/gnu/glibc/master/malloc/malloc.c:void * weak_function aligned_alloc (size_t alignment, size_t bytes) { /* Similar to memalign, but starting with ISO C17 the standard requires an error for alignments that are not supported by the implementation. Valid alignments for the current implementation are non-negative powers of two. */ if (!powerof2 (alignment) || alignment == 0) { __set_errno (EINVAL); return NULL; } return _mid_memalign (alignment, bytes); } alx@devuan:~$ grepc -tfd memalign ~/src/musl/libc/master/ /home/alx/src/musl/libc/master/src/malloc/memalign.c:void *memalign(size_t align, size_t len) { return aligned_alloc(align, len); }OpenBSD's libc isn't: https://github.com/openbsd/src/blob/master/lib/libc/stdlib/malloc.c#L2336 And it is understandable, since at some point it was *mandated* to fail in this case, and not be permissive. I know it's likely outside linux-man's purview, but it's definitely something to consider for portable application developers.
Hmmm, we didn't know of that. I asked back when the page was patched if anyone knew of any system that implemented the C11 behavior, and nobody knew about any such. Thanks! That is definitely something that we should document in this project. I'll prepare a patch.
quoted
Prior to that implementation, glibc had aligned_alloc(3) as an alias for memalign(3).
[...] [Reordered]
quoted
On Wed, Dec 10, 2025 at 05:29:39PM +0100, Eugene Syromyatnikov wrote:quoted
On Wed, Dec 10, 2025 at 1:40 PM Alejandro Colomar [off-list ref] wrote:quoted
From all of these functions, ISO C's aligned_alloc(3) is the only one that programmers should be using.I strongly disagree with this assessment; moreover, I'd argue that this is the function that people should avoid, due to its inconsistent;y defined behavior in various versions of the standard,The only standard that was different was C11, but C17 --which is a bug fix, and thus, the same standard-- fixed that, and the standard has been consistent ever since. All known implementations conform to C17 and C23.So, you see, here lies a problem, conforming to which standard? As an application developer, I don't know whether requesting a large alignment would lead to success, failure, or rm-rf-ing my whole system (as the standard specified UB in that case before DR460[1]) by a "conforming" libc implementation, because libc, generally, is out of my control;
If noone had ever implemented C11, we could have treated it as hypothetical UB. But since you showed that OpenBSD has implemented it, we do have a problem. The good news is that it just fails. So far, no implementation has UB; it's only theoretical, and after the DR fixes, no new implementation should ever implement it with UB. Ingo, OpenBSD seems to be implementing C11's aligned_alloc(3). Would you mind checking if implementing the latest revision of aligned_alloc(3) is a possibility in OpenBSD? C17 had important changes, which remain in C23, and have also been standardized by POSIX.1-2024.
so, in reality, I'm only limited to alignments that are divisors of the object size for "safe" use, which renders the function useless for practical purposes. The fact that the definition of restrictions has changed so many times and so wildly renders it so toxic that I'd advise against using it in the foreseeable future and just stick to posix_memalign, despite its peculiarities in terms of argument handling.
After seeing this new information, I agree with you that
posix_memalign(3) seems more portable.
Maybe the manual page could show a wrapper to workaround the ugly API of
posix_memalign(3):
static inline void *
my_posix_memalign(size_t alignment, size_t size)
{
int e;
void *p;
e = posix_memalign(&p, alignment, size);
if (e != 0) {
errno = e;
return NULL;
}
return p;
}
The other aspect (which is irrelevant to this discussion, but doesn't adds points to aligned_alloc in terms of practical usability) is that MS CRT doesn't support it at all because it is oh so special in terms of aligned allocations.
Does MS support posix_memalign(3)? What's the problem with aligned_alloc(3)?
[1] https://open-std.org/JTC1/SC22/WG14/www/docs/summary.htm#dr_460
Have a lovely night! Alex -- <https://www.alejandro-colomar.es>
Attachments
- signature.asc [application/pgp-signature] 833 bytes