4

The C++ standard states, regarding the std::aligned_storage template, that

Align shall be equal to alignof(T) for some type T or to default-alignment.

Does that mean that there must be such a type in the program, or that it must be possible to make such a type? In particular, the possible implementation suggested on cppreference is

template<std::size_t Len, std::size_t Align /* default alignment not implemented */>
struct aligned_storage {
    typedef struct {
        alignas(Align) unsigned char data[Len];
    } type;
};

It seems like this makes a type with that alignment, if possible (that is, if Align is a valid alignment). Is that behavior required, or is it undefined behavior to specify an Align if such a type does not already exist?

And, perhaps more importantly, is it plausible in practice that the compiler or standard library would fail to do the right thing in this case, assuming that Align is at least a legal alignment for a type to have?

6
  • T is the type of the hypothetical object you want to store, whose alignment should match or evenly divide Align and whose size is at least Len. Are you asking what happens if you were to specify a strange value for Align? (like 13) Commented Mar 28, 2017 at 19:19
  • 1
    You aren’t allowed to have non-power-of-two alignments, from a different thing in the standard. However, you are allowed to specify larger powers of two than would naturally appear, like 4096 bytes to align with memory pages. I don’t know if you’re allowed to specify them with std::aligned_storage or if you manually need to create the storage with the over-alignment. That’s what I’m asking about. Commented Mar 28, 2017 at 19:21
  • then yes, std::aligned_storage can be used to over-align objects. Ts alignment doesn't have to match Align it just has to be a divisor. Commented Mar 28, 2017 at 19:24
  • 1
    Here, T is not necessarily the same as the type you want to put in the storage. This says that if I want to use a 4096-byte std::aligned_storage there must be a 4096-byte aligned data type. I know that if I have a 4096-byte aligned storage I can use it for anything which requires an 8-byte alignment (or any other factor of 4096), but that doesn’t tell me if I can construct such a storage in the first place. Commented Mar 28, 2017 at 19:29
  • I get what you're saying. I wouldn't expect that there must a 4096-aligned type in-order to use it. I feel like this is a miss-wording. though just in case, you could always define a type that has that alignment Commented Mar 28, 2017 at 19:40

1 Answer 1

3

You can always attempt to make a type with arbitrary (valid) alignment N:

template <std::size_t N> struct X { alignas(N) char c; };

When N is greater than the default alignment, X has extended alignment. The support for extended alignment is implementation-defined, and [dcl.align] says:

if the constant expression does not evaluate to an alignment value (6.11), or evaluates to an extended alignment and the implementation does not support that alignment in the context of the declaration, the program is ill-formed.

Therefore, when you attempt to say X<N> for an extended alignment that is not supported, you will face a diagnostic. You can now use the existence (or otherwise) of X<N> to justify the validity of the specialization aligned_storage<Len, N> (whose condition is now met with T = X<N>).

Since aligned_storage will effectively use something like X internally, you don't even have to actually define X. It's just a mental aid in the explanation. The aligned_storage will be ill-formed if the requested alignment is not supported.

Sign up to request clarification or add additional context in comments.

2 Comments

I suppose it would be implausible for aligned_storage to not use something like X internally, although I am also curious if it’s standards-compliant to assume it does. From my understanding, the requirement that X could be defined (if the relevant N is supported) is enough to satisfy the requirement I quoted in the standard; is that correct?
@DanielH: I would consider anything else a hostile reading of the standard. At best you could stick X into your autoconf script to test if your platform can build it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.