aligned_alloc function requirements
Asked Answered
S

2

6

I'm looking at the explanation of aligned-alloc(): http://en.cppreference.com/w/c/memory/aligned_alloc

void *aligned_alloc( size_t alignment, size_t size );

"Allocate size bytes of uninitialized storage whose alignment is specified by alignment. The size parameter must be an integral multiple of alignment."

However, the example code uses it like this:

int *p2 = aligned_alloc(1024, 10*sizeof *p2);

10*sizeof *p equals 40, so it's not an integral multiple of 1024.

What do I misunderstand?

Sporulate answered 8/12, 2016 at 3:37 Comment(9)
I think typo: Perhaps it was meant to also have "24" as in int *p2 = aligned_alloc(1024, 1024*sizeof *p2); or int *p2 = aligned_alloc(10, 10*sizeof *p2);? Of course maybe the size of int could be 2,560, but I doubt that.Ferde
It might have been a typo, but the code compiles and runs fine as is. I'm using GCC 4.9.Sporulate
For what it's worth, cppreference dot com is generally a very bad source for information about C++ and even worse for information about C. It's more like someone's imprecise paraphrase of what the languages say rather than explaining and clarifying their requirements.Fundamentalism
@R.. if you find a problem with cppreference's explanations or clarifications, it is a public wiki. The fix is only an edit away, and it will benefit many programmers. Fixing this example only took a minute, and it already had quite a bit more info than 7.22.3.1.Titanite
@Cubbi: Fixing it is a problem of local vs global optimization; when the resource as a whole is bad, making minor fixes here and there lends to its credibility while leaving in-place heaps of wrong information. SO documentation would probably be a much better place to spend one's time writing.Fundamentalism
I'm still confused though: does n2072 ask to revert DR 460 back to undefined behavior, or does it want small size values be completely valid?Sporulate
@R.. It would both lend you credibility and help the users if you point out some of those "heaps". As for SO docs, competition makes everything better (just compare cplusplus.com from before cppreference went public vs today)Titanite
@Sporulate as far as I can see, it wants to legalize any positive size, which is the only sane option (otherwise the users will just keep using posix_memalign and whatever other APIs they have)Titanite
@MichaelSB: Since the alignment of a type always divides its size, allocation sizes that are not multiples of alignment mostly don't make sense. Notable exception is flexible array members at the end.Fundamentalism
S
4

Actually, it seems like C11 standard cannot make up its own mind, and keeps changing the requirements: initially it was an undefined behavior, then with DR 460 they changed it to fail and return null pointer, and now it seems like they want to change it to accept any values as arguments: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2072.htm

And compilers seem to not care about those restrictions.

Sporulate answered 8/12, 2016 at 4:38 Comment(2)
It's really a shame that the standards committee changed it so it's required to fail for SIMD use-cases like allocating a 64B-aligned array of float with a non-multiple-of-16 count. Or for allocating a big buffer aligned to a 2M hugepage boundary. It was the only function with a nice API that returned pointers you could pass to free. It's nice that actual implementations don't follow that stupid design, but it means that portable aligned allocation is still farther from being achievable.Olid
The requirement that the size must be a multiple of alignment is stupid, considering that all the other allocator functions may allocate whatever they want as long as it's greater or equal the requested size. So even if there's a technical reason for the requirement (I'm curious what it is), aligned_alloc can simply round up the function internally. I also think the alignment argument shouldn't be the required alignment directly but rather its base 2 logarithm. That way there'd be no invalid inputs to that function.Teniacide
M
1

According to your own reference:

Passing a size which is not an integral multiple of alignment or a alignment which is not valid or not supported by the implementation causes the function to fail and return a null pointer (C11, as published, specified undefined behavior in this case, this was corrected by DR 460).

It's possible a compiler that accepts this following the C11 rules, having not updated for DR 460, and decided "undefined" meant "Works" in this case. Of course, it could also mean "Succeeds, but is not aligned or allocates alignment bytes minimum" too. It's undefined. shrugs

For the example code, it could have been written before that clarification and not aligned with the standard requirements, or there was a typo writing it (as suggested in the comments, it may have been intended to be 1024 * sizeof *p2).

Meshed answered 8/12, 2016 at 3:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.