Skip to content

Create alignas specifier page #4742

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/cpp/align-cpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ helpviewer_keywords: ["align __declspec keyword", "__declspec keyword [C++], ali
---
# `align` (C++)

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).
In Visual Studio 2015 and later, use the C++11 standard [**`alignas`** specifier](../cpp/alignas-specifier.md) to control alignment. For more information, see [Alignment](../cpp/alignment-cpp-declarations.md).

**Microsoft Specific**

Expand Down
103 changes: 103 additions & 0 deletions docs/cpp/alignas-specifier.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
---
description: "Learn more about: alignas Specifier"
title: "alignas Specifier"
ms.date: "09/30/2023"
f1_keywords: ["alignas"]
helpviewer_keywords: ["alignas [C++]", "alignment of structures", "__alignof keyword [C++]", "alignof [C++]", "types [C++], alignment requirements"]
---
# `alignas` Specifier

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. For more information, see [Alignment](../cpp/alignment-cpp-declarations.md).

## Syntax

```cpp
alignas( type-id )
alignas( expression )
alignas( pack... )
```

## Remarks

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:

```cpp
struct alignas(8) S1
{
int x;
};

static_assert(alignof(S1) == 8, "alignof(S1) should be 8");
```

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.

```cpp
class alignas(4) alignas(16) C1 {};

// `alignas(0)` ignored
union alignas(0) U1
{
int i;
float f;
};

union U2
{
int i;
float f;
};

static_assert(alignof(C1) == 16, "alignof(C1) should be 16");
static_assert(alignof(U1) == alignof(U2), "alignof(U1) should be equivalent to alignof(U2)");
```

Instead of using an integral constant for the alignment value, you may also choose to supply a type:

```cpp
struct alignas(double) S2
{
int x;
};

static_assert(alignof(S2) == alignof(double), "alignof(S2) should be equivalent to alignof(double)");
```

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).

A template parameter pack can also be used (`alignas ( pack... )`). It functions on the same concept where only the strictest alignment is effective.

```cpp
template <typename... Ts>
class alignas(Ts...) C2
{
char c;
};

static_assert(alignof(C2<>) == 1, "alignof(C2<>) should be 1");
// Empty angle brackets can be omitted since C++17
// static_assert(alignof(C2) == 1, "alignof(C2) should be 1");
static_assert(alignof(C2<short, int>) == 4, "alignof(C2<short, int>) should be 4");
static_assert(alignof(C2<int, float, double>) == 8, "alignof(C2<int, float, double>) should be 8");
```

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.

```cpp
// Declaration of `C3`
class alignas(16) C3;

// Definition of `C3` (with differing alignment requirement)
class alignas(32) C3 {}; // C2023, 'C3': Alignment (32) different from prior declaration (16)

int main()
{
alignas(2) int x; // ill-formed, since the natural alignment of `int` is 4
}
```

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).

## See also

[`#pragma pack`](../preprocessor/pack.md)
4 changes: 2 additions & 2 deletions docs/cpp/alignment-cpp-declarations.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ ms.assetid: a986d510-ccb8-41f8-b905-433df9183485

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.

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.
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.

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.

Expand Down Expand Up @@ -92,7 +92,7 @@ adr offset element

## `alignof` and `alignas`

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.
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.

## Example

Expand Down
2 changes: 1 addition & 1 deletion docs/cpp/keywords-cpp.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Keywords are predefined reserved identifiers that have special meanings. They ca

:::row:::
:::column:::
[`alignas`](align-cpp.md)\
[`alignas`](alignas-specifier.md)\
[`alignof`](alignof-operator.md)\
[`and`](logical-and-operator-amp-amp.md) <sup>b</sup>\
[`and_eq`](assignment-operators.md) <sup>b</sup>\
Expand Down
2 changes: 2 additions & 0 deletions docs/cpp/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ items:
href: ../cpp/decltype-cpp.md
- name: Attributes
href: ../cpp/attributes.md
- name: alignas specifier
href: ../cpp/alignas-specifier.md
- name: Built-in operators, precedence, and associativity
items:
- name: Built-in operators, precedence, and associativity
Expand Down