Does new char actually guarantee aligned memory for a class type?
Asked Answered
C

2

63

Is allocating a buffer via new char[sizeof(T)] guaranteed to allocate memory which is properly aligned for the type T, where all members of T has their natural, implementation defined, alignment (that is, you have not used the alignas keyword to modify their alignment).

I have seen this guarantee made in a few answers around here but I'm not entirely clear how the standard arrives at this guarantee. 5.3.4-10 of the standard gives the basic requirement: essentially new char[] must be aligned to max_align_t.

What I'm missing is the bit which says alignof(T) will always be a valid alignment with a maximum value of max_align_t. I mean, it seems obvious, but must the resulting alignment of a structure be at most max_align_t? Even point 3.11-3 says extended alignments may be supported, so may the compiler decide on its own a class is an over-aligned type?

Clipfed answered 14/5, 2012 at 17:3 Comment(12)
Finally, a good question. Can I upvote a whole bunch of times? (CLICK CLICK CLICK)Silviasilviculture
@JohnDibling: by yourself, no, but there's a bunch of us fortunately :DShortcut
Not an answer, but can't you just play it safe and use new T and cast the result? Oh, and +1 for teaching me a new tag. I never heard about language-lawyer.Precedence
What the spec says about sizeof must be relevant too: 5.3.3-2 says "When applied to a class, the result is the number of bytes in an object of that class including any padding required for placing objects of that type in an array"Imprison
I still don't understand the question.Commixture
There is a note in [basic.align]/3 -- [note every over-aligned type is or contains a class type to which extended alignment applies (possibly through a non-static data member) end note]. I can't find the normative reference for this, but it seems to imply that your T will never be over-aligned.Hind
@Mankarse: looks like it actually answers the question then. Even though it seems quite hand-wavy, I have not found better :xShortcut
@Mankarse, let's assume the note is normative. But does it somehow forbid the compiler from applying an extended alignment on its own?Clipfed
@edA-qamort-ora-y: I thought it did, but on a rereading I realise that it actually doesn't...Hind
@edA-qamort-ora-y: I think it is the intention, however the is is quite weird. Also inheritance is not clearly featured... it's a weird quote, definitely, but it is the only quote in the standard which seems to actually attempt to defined what over-aligned means !!Shortcut
There is also another note which seems to explicitly allow this [expr.new]/10 -- [ Note: Because allocation functions are assumed to return pointers to storage that is appropriately aligned for objects of any type with fundamental alignment, this constraint on array allocation overhead permits the common idiom of allocating character arrays into which objects of other types will later be placed. — end note ]. [continued...]Hind
That said -- the normative text still requires an object with a fundamental alignment requirement, and there does not seem to be anything that states that alignas is the only way in which over-aligned types can be created.Hind
S
6

What I'm missing is the bit which says alignof(T) will always be a valid alignment with a maximum value of max_align_t. I mean, it seems obvious, but must the resulting alignment of a structure be at most max_align_t ? Even point 3.11-3 says extended alignments may be supported, so may the compiler decide on its own a class is an over-aligned type ?

As noted by Mankarse, the best quote I could get is from [basic.align]/3:

A type having an extended alignment requirement is an over-aligned type. [ Note: every over-aligned type is or contains a class type to which extended alignment applies (possibly through a non-static data member). —end note ]

which seems to imply that extended alignment must be explicitly required (and then propagates) but cannot

I would have prefer a clearer mention; the intent is obvious for a compiler-writer, and any other behavior would be insane, still...

Shortcut answered 14/5, 2012 at 17:28 Comment(2)
It uses the word applied, could a compiler apply an extended alignment on its own? Or do points 1/2 in the paragraph to imply that any alignment applied by the compiler must be at most max_align_t?Clipfed
@edA-qamort-ora-y: [dcl.align]/1 also uses the verb apply: "An alignment-specifier may be applied to", so I would expect that this means that it is where the applies come from and it should be explicitly required but...Shortcut
C
18

The expressions new char[N] and new unsigned char[N] are guaranteed to return memory sufficiently aligned for any object. See §5.3.4/10 "[...] For arrays of char and unsigned char, the difference between the result of the new-expression and the address returned by the allocation function shall be an integral multiple of the strictest fundamental alignment requirement (3.11) of any object type whose size is no greater than the size of the array being created. [ Note: Because allocation functions are assumed to return pointers to storage that is appropriately aligned for objects of any type with fundamental alignment, this constraint on array allocation overhead permits the common idiom of allocating character arrays into which objects of other types will later be placed. —end note ]".

From a stylistic point of view, of course: if what you want is to allocate raw memory, it's clearer to say so: operator new(N). Conceptually, new char[N] creates N char; operator new(N) allocates N bytes.

Cuddle answered 14/5, 2012 at 18:31 Comment(2)
It's only required to provide alignment for a type with a fundamental alignment requirement, up to max_align_t. so the question is whether the compiler may create class types of extended alignment, which would thus not be fundamentally aligned.Clipfed
What does this answer add? The standards quote is the same section is referenced in the question.Commixture
S
6

What I'm missing is the bit which says alignof(T) will always be a valid alignment with a maximum value of max_align_t. I mean, it seems obvious, but must the resulting alignment of a structure be at most max_align_t ? Even point 3.11-3 says extended alignments may be supported, so may the compiler decide on its own a class is an over-aligned type ?

As noted by Mankarse, the best quote I could get is from [basic.align]/3:

A type having an extended alignment requirement is an over-aligned type. [ Note: every over-aligned type is or contains a class type to which extended alignment applies (possibly through a non-static data member). —end note ]

which seems to imply that extended alignment must be explicitly required (and then propagates) but cannot

I would have prefer a clearer mention; the intent is obvious for a compiler-writer, and any other behavior would be insane, still...

Shortcut answered 14/5, 2012 at 17:28 Comment(2)
It uses the word applied, could a compiler apply an extended alignment on its own? Or do points 1/2 in the paragraph to imply that any alignment applied by the compiler must be at most max_align_t?Clipfed
@edA-qamort-ora-y: [dcl.align]/1 also uses the verb apply: "An alignment-specifier may be applied to", so I would expect that this means that it is where the applies come from and it should be explicitly required but...Shortcut

© 2022 - 2024 — McMap. All rights reserved.