Skip to content

Commit ce6f334

Browse files
authored
Create alignas specifier page
1 parent c192538 commit ce6f334

4 files changed

Lines changed: 104 additions & 3 deletions

File tree

‎docs/cpp/align-cpp.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ helpviewer_keywords: ["align __declspec keyword", "__declspec keyword [C++], ali
77
---
88
# `align` (C++)
99

10-
In Visual Studio 2015 and later, use the C++11 standard **`alignas`** specifier to control alignment. For more information, see [Alignment](../cpp/alignment-cpp-declarations.md).
10+
In Visual Studio 2015 and later, use the C++11 standard [**`alignas`** specifier](../cpp/alignas-specifier.md) to control alignment.
1111

1212
**Microsoft Specific**
1313

‎docs/cpp/alignas-specifier.md‎

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
---
2+
description: "Learn more about: alignas Specifier"
3+
title: "alignas Specifier"
4+
ms.date: "09/30/2023"
5+
f1_keywords: ["alignas"]
6+
helpviewer_keywords: ["alignas [C++]", "alignment of structures", "__alignof keyword [C++]", "alignof [C++]", "types [C++], alignment requirements"]
7+
---
8+
# `alignas` Specifier
9+
10+
The **`alignas`** specifier changes the alignment of a type or object. You should prefer usage of **`alignas`** over [`__declspec(align(#))`](align-cpp.md) for code portability.
11+
12+
## Syntax
13+
14+
```cpp
15+
alignas( type-id )
16+
alignas( expression )
17+
alignas( pack... )
18+
```
19+
20+
## Remarks
21+
22+
You can use **`alignas`** specifier on a **`struct`**, **`class`**, **`union`**, or variable declaration. For `alignas( expression )`, the expression must be an integral constant expression that are powers of 2 (1, 2, 4, 8, 16, 32, 64...) or equal to `0`. All other expressions are ill-formed. A common use-case would be to control the alignment of a user-defined type as follows:
23+
24+
```cpp
25+
struct alignas(8) S1
26+
{
27+
int x;
28+
};
29+
30+
static_assert(alignof(S1) == 8, "alignof(S1) should be 8");
31+
```
32+
33+
See [`alignof`](alignof-operator.md) for more infomation about how to get the alignment value. When multiple **`alignas`** target the same declaration, the strictest alignment requirement will be taken (largest value). When the integral constant expression is `0`, the **`alignas`** will be ignored.
34+
35+
```cpp
36+
class alignas(4) alignas(16) C1 {};
37+
38+
// `alignas(0)` ignored
39+
union alignas(0) U1
40+
{
41+
int i;
42+
float f;
43+
};
44+
45+
union U2
46+
{
47+
int i;
48+
float f;
49+
};
50+
51+
static_assert(alignof(C1) == 16, "alignof(C1) should be 16");
52+
static_assert(alignof(U1) == alignof(U2), "alignof(U1) should be equivalent to alignof(U2)");
53+
```
54+
55+
Instead of using an integral constant for the alignment value, you may also choose to supply a type:
56+
57+
```cpp
58+
struct alignas(double) S2
59+
{
60+
int x;
61+
};
62+
63+
static_assert(alignof(S2) == alignof(double), "alignof(S2) should be equivalent to alignof(double)");
64+
```
65+
66+
As seen from the [`static_assert`](static-assert.md), `alignas( type-id )` is analogous to `alignas(alignof( type ))` (identical to using an integral constant expression of the result).
67+
68+
A template parameter pack can also be used (`alignas ( pack... )`). It functions on the same concept where only the strictest alignment is effective.
69+
70+
```cpp
71+
template <typename... Ts>
72+
class alignas(Ts...) C2
73+
{
74+
char c;
75+
};
76+
77+
static_assert(alignof(C2<>) == 1, "alignof(C2<>) should be 1");
78+
// Empty angle brackets can be omitted since C++17
79+
// static_assert(alignof(C2) == 1, "alignof(C2) should be 1");
80+
static_assert(alignof(C2<short, int>) == 4, "alignof(C2<short, int>) should be 4");
81+
static_assert(alignof(C2<int, float, double>) == 8, "alignof(C2<int, float, double>) should be 8");
82+
```
83+
84+
The resulting alignment (largest) of all the **`alignas`** (if more than 1) cannot be less than the natural alignment (without having any **`alignas`** specifier). Declaration and definition of user-defined types must match in alignment requirement.
85+
86+
```cpp
87+
// Declaration of `C3`
88+
class alignas(16) C3;
89+
90+
// Definition of `C3` (with differing alignment requirement)
91+
class alignas(32) C3 {}; // C2023, 'C3': Alignment (32) different from prior declaration (16)
92+
93+
int main()
94+
{
95+
alignas(2) int x; // ill-formed, since the natural alignment of `int` is 4
96+
}
97+
```
98+
99+
For more information, see error [C2023](../error-messages/compiler-errors-1/compiler-error-c2023.md) and warning [C4359](../error-messages/compiler-warnings/compiler-warning-level-3-c4359.md).

‎docs/cpp/alignment-cpp-declarations.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ ms.assetid: a986d510-ccb8-41f8-b905-433df9183485
88

99
One of the low-level features of C++ is the ability to specify the precise alignment of objects in memory to take maximum advantage of a specific hardware architecture. By default, the compiler aligns class and struct members on their size value: **`bool`** and **`char`** on 1-byte boundaries, **`short`** on 2-byte boundaries, **`int`**, **`long`**, and **`float`** on 4-byte boundaries, and **`long long`**, **`double`**, and **`long double`** on 8-byte boundaries.
1010

11-
In most scenarios, you never have to be concerned with alignment because the default alignment is already optimal. In some cases, however, you can achieve significant performance improvements, or memory savings, by specifying a custom alignment for your data structures. Before Visual Studio 2015 you could use the Microsoft-specific keywords **`__alignof`** and **`__declspec(align)`** to specify an alignment greater than the default. Starting in Visual Studio 2015 you should use the C++11 standard keywords **`alignof`** and **`alignas`** for maximum code portability. The new keywords behave in the same way under the hood as the Microsoft-specific extensions. The documentation for those extensions also applies to the new keywords. For more information, see [`alignof` Operator](../cpp/alignof-operator.md) and [align](../cpp/align-cpp.md). The C++ standard doesn't specify packing behavior for alignment on boundaries smaller than the compiler default for the target platform, so you still need to use the Microsoft [`#pragma pack`](../preprocessor/pack.md) in that case.
11+
In most scenarios, you never have to be concerned with alignment because the default alignment is already optimal. In some cases, however, you can achieve significant performance improvements, or memory savings, by specifying a custom alignment for your data structures. Before Visual Studio 2015 you could use the Microsoft-specific keywords **`__alignof`** and **`__declspec(align)`** to specify an alignment greater than the default. Starting in Visual Studio 2015 you should use the C++11 standard keywords **`alignof`** and **`alignas`** for maximum code portability. The new keywords behave in the same way under the hood as the Microsoft-specific extensions. The documentation for those extensions also applies to the new keywords. For more information, see [`alignof` Operator](../cpp/alignof-operator.md), [`alignas` Specifier](../cpp/alignas-specifier.md) and [align](../cpp/align-cpp.md). The C++ standard doesn't specify packing behavior for alignment on boundaries smaller than the compiler default for the target platform, so you still need to use the Microsoft [`#pragma pack`](../preprocessor/pack.md) in that case.
1212

1313
Use the [aligned_storage class](../standard-library/aligned-storage-class.md) for memory allocation of data structures with custom alignments. The [aligned_union class](../standard-library/aligned-union-class.md) is for specifying alignment for unions with non-trivial constructors or destructors.
1414

@@ -92,7 +92,7 @@ adr offset element
9292

9393
## `alignof` and `alignas`
9494

95-
The **`alignas`** type specifier is a portable, C++ standard way to specify custom alignment of variables and user defined types. The **`alignof`** operator is likewise a standard, portable way to obtain the alignment of a specified type or variable.
95+
The **`alignas`** specifier is a portable, C++ standard way to specify custom alignment of variables and user defined types. The **`alignof`** operator is likewise a standard, portable way to obtain the alignment of a specified type or variable.
9696

9797
## Example
9898

‎docs/cpp/toc.yml‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ items:
122122
href: ../cpp/decltype-cpp.md
123123
- name: Attributes
124124
href: ../cpp/attributes.md
125+
- name: alignas specifier
126+
href: ../cpp/alignas-specifier.md
125127
- name: Built-in operators, precedence, and associativity
126128
items:
127129
- name: Built-in operators, precedence, and associativity

0 commit comments

Comments
 (0)