On 04/02/2015 06:45 PM, Joseph Myers wrote: >> Follow-up question: Can malloc return a pointer which is not aligned to >> _Alignof (max_align_t)? >> >> This happens with most mallocs on x86_64 for sizes of 8 or less, for >> which these mallocs only provide an alignment of 8. >> >> DR445 does not seem to have reached consensus on that point. > > I see no lack of consensus. > <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1892.htm#dr_445> says > "The proposed changes have raised no concerns and so the committee has > agreed to use them as the following Proposed Technical Corrigendum.", and > nothing regarding alignment for small allocations has changed since > DR#075. "suitably aligned so that it may be assigned to a pointer to any > type of object with a fundamental alignment requirement" (unchanged > wording in 7.22.3) implies being suitably aligned for all types with > fundamental alignment requirements; otherwise such assignment would result > in undefined behavior at runtime.
Okay, let me see if I got this right. If I declare a type with an _Alignas specification, requiring an alignment which is less than _Alignof (max_align_t), that is a, fundamental alignment, then I can allocate such an object with malloc. That is, this code is valid: struct S { _Alignas (max_align_t) char a; }; struct S *p = malloc (sizeof (struct S)); On x86-64, GCC would be free to assume that p is 16-byte-aligned. But I see nothing in the x86-64 ABI document that implies that malloc (1) must be 16-byte-aligned. The fact that there are types of larger size which require greater alignment does not mean that small objects must have such an alignment as well. jemalloc and tcmalloc will happily allocate 8-byte-aligned objects for sizes less than 16. I'm sure there are other mallocs with similar behavior. Before C11, this was perfectly conforming. I doubt it was the intention of the standard committee to make these mallocs non-conforming and require heap allocation of small objects to waste extra space. Contrary to what I thought initially, it is not possible to reduce the alignment of max_align_t because it still has to match that of long double, a basic type which is defined to have fundamental alignment. So my conclusion now is that DR445 was resolved incorrectly. Maybe the entire concept of max_align_t is broken. -- Florian Weimer / Red Hat Product Security