Thread (49 messages) 49 messages, 4 authors, 2025-12-23

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

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help