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

Reply via email to