Reputation: 4195
I have tested this code on ideone.com and it outputs 16
as it should. However when I try it in Visual Studio 2013 it shows 8
. Is it a bug or lack of C++11 support from the compiler?
#include <iostream>
#include <type_traits>
using namespace std;
using float_pack = aligned_storage<4 * sizeof(float), 16>::type;
int main() {
cout << alignment_of<float_pack>::value << endl;
return 0;
}
I have used alignment_of because MSVC doesn't support alignof
.
Edit: I see that I can't get 16
alignment with aligned_storage
. But why this snippet is ok?
#include <iostream>
#include <type_traits>
#include <xmmintrin.h>
using namespace std;
__declspec(align(16)) struct float_pack {
float x[4];
};
int main()
{
cout << alignment_of<float_pack>::value << endl;
}
Output is 16
. Does that mean that compiler can provide larger alignment when using extensions? Why I can't achieve the same result with aligned_storage
? Only because MSVC doesn't provide that with aligned_storage
?
Upvotes: 9
Views: 2397
Reputation: 158599
It looks like std::max_align_t
is 8
, see it live:
std::cout << alignment_of<std::max_align_t>::value << '\n';
In the draft C++ standard section 3.11
Alignment it says:
A fundamental alignment is represented by an alignment less than or equal to the greatest alignment sup- ported by the implementation in all contexts, which is equal to alignof(std::max_align_t) (18.2).[...]
Which says that that is the max alignment the implementation supports, this seems to be backed up by this boost doc which says:
An extended alignment is represented by an alignment greater than alignof(std::max_align_t). It is implementation-defined whether any extended alignments are supported and the contexts in which they are supported. A type having an extended alignment requirement is an over-aligned type.
max_align_t
is by the standard tied to the fundamental alignment which James as informed us is 8 bytes
. Whereas an extension does not have to stick to this as long as it is documented which if we read the docs for __declspec align we see that it says:
Writing applications that use the latest processor instructions introduces some new constraints and issues. In particular, many new instructions require that data must be aligned to 16-byte boundaries. Additionally, by aligning frequently used data to the cache line size of a specific processor, you improve cache performance. For example, if you define a structure whose size is less than 32 bytes, you may want to align it to 32 bytes to ensure that objects of that structure type are efficiently cached.
[...]
Without __declspec(align(#)), Visual C++ aligns data on natural boundaries based on the size of the data, for example 4-byte integers on 4-byte boundaries and 8-byte doubles on 8-byte boundaries. Data in classes or structures is aligned within the class or structure at the minimum of its natural alignment and the current packing setting (from #pragma pack or the /Zp compiler option).
Upvotes: 6
Reputation: 45684
std::aligned_storage
defines a type of size Len
, with the alignment requirement you provide. If you ask for an unsupported alignment, your program is ill-formed.
template <std::size_t Len, std::size_t Align
= default-alignment > struct aligned_storage;
Len shall not be zero. Align shall be equal to
alignof(T)
for some typeT
or to default-alignment.The value of default-alignment shall be the most stringent alignment requirement for any C++ object type whose size is no greater than
Len
(3.9). The member typedef type shall be a POD type suitable for use as uninitialized storage for any object whose size is at mostLen
and whose alignment is a divisor ofAlign
.[ Note: A typical implementation would define aligned_storage as:
template <std::size_t Len, std::size_t Alignment>
struct aligned_storage {
typedef struct {
alignas(Alignment) unsigned char __data[Len];
} type;
};
—end note ]
And for alignas
:
7.6.2 Alignment specifier [dcl.align]
1 An alignment-specifier may be applied to a variable or to a class data member, but it shall not be applied to a bit-field, a function parameter, the formal parameter of a catch clause (15.3), or a variable declared with the register storage class specifier. An alignment-specifier may also be applied to the declaration of a class or enumeration type. An alignment-specifier with an ellipsis is a pack expansion (14.5.3).
2 When the alignment-specifier is of the form alignas( assignment-expression ):
— the assignment-expression shall be an integral constant expression
— if the constant expression evaluates to a fundamental alignment, the alignment requirement of the declared entity shall be the specified fundamental alignment
— if the constant expression evaluates to an extended alignment and the implementation supports that alignment in the context of the declaration, the alignment of the declared entity shall be that alignment
— if the constant expression evaluates to an extended alignment and the implementation does not support
that alignment in the context of the declaration, the program is ill-formed — if the constant expression evaluates to zero, the alignment specifier shall have no effect
— otherwise, the program is ill-formed.
Upvotes: 2