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
?
The /ALIGN option specifies the alignment of each section within the linear address space of the program. The number argument is in bytes and must be a power of two. The default is 4K (4096). The linker issues a warning if the alignment produces an invalid image.
Unless you're writing an application such as a device driver, you shouldn't need to modify the alignment. It's possible to modify the alignment of a particular section with the align parameter to the /SECTION option. The alignment value that you specify can't be smaller than the largest section alignment.
This differentiation still exists in current CPUs, and still some have only instructions that perform aligned accesses. To take into account this issue, the C standard has alignment rules in place, and so the compilers exploit them to generate efficient code whenever possible.
The alignment value in bytes. The /ALIGN linker option specifies the alignment of each section within the linear address space of the program. The number argument is in bytes and must be a power of two. The default is 4K (4096). The linker issues a warning if the alignment produces an invalid image.
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).
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With