Skip to content

Commit 5f1d249

Browse files
authored
Merge pull request #5206 from MicrosoftDocs/main
2/21/2024 AM Publish
2 parents 46a75fc + be5368c commit 5f1d249

File tree

1 file changed

+43
-2
lines changed

1 file changed

+43
-2
lines changed

docs/overview/cpp-conformance-improvements.md

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "C++ conformance improvements in Visual Studio 2022"
33
description: "Microsoft C++ in Visual Studio is improving standards conformance and fixing bugs regularly."
4-
ms.date: 2/6/2024
4+
ms.date: 02/20/2024
55
ms.service: "visual-cpp"
66
ms.subservice: "cpp-lang"
77
---
@@ -21,6 +21,47 @@ Visual Studio 2022 version 17.9 contains the following conformance improvements,
2121

2222
For a broader summary of changes made to the Standard Template Library, see [STL Changelog VS 2022 17.9](https://github.com/microsoft/STL/wiki/Changelog#vs-2022-179).
2323

24+
### Application of `_Alignas` on a structured type in C
25+
26+
In versions of Visual C++ before Visual Studio 2022 version 17.9, when `_Alignas` appeared next to a structure type in a declaration, it wasn't applied correctly according to the ISO-C Standard. For example:
27+
28+
```c
29+
// compile with /std:c17
30+
#include <stddef.h>
31+
struct Outer
32+
{
33+
_Alignas(32) struct Inner { int i; } member1;
34+
struct Inner member2;
35+
};
36+
static_assert(offsetof(struct Outer, member2)==4, "incorrect alignment");
37+
```
38+
39+
According to the ISO-C Standard, this code should compile without the `static_assert` emitting a diagnostic. The `_Alignas` directive applies only to the member variable `member1`. It must not change the alignment of `struct Inner`. However, before release 17.9.1 of Visual Studio, the diagnostic "incorrect alignment" was emitted. The compiler aligned `member2` to a 32 byte offset within `struct Outer`.
40+
41+
Fixing this is a binary breaking change, so when this change in behavior is applied a warning is emitted. For the preceding code, Warning C5274, "`_Alignas` no longer applies to the type 'Inner' (only applies to declared data objects)" is now emitted at warning level 1.
42+
43+
In previous versions of Visual Studio, `_Alignas` was ignored when it appeared next to an anonymous type declaration. For example:
44+
45+
```c
46+
// compile with /std:c17
47+
#include <stddef.h>
48+
struct S {
49+
_Alignas(32) struct { int anon_member; };
50+
int k;
51+
};
52+
static_assert(offsetof(struct S, k)==4, "incorrect offsetof");
53+
static_assert(sizeof(struct S)==32, "incorrect size");
54+
```
55+
56+
Previously, both `static_assert` statements failed when compiling this code. The code now compiles, but with the following level 1 warnings:
57+
58+
```c
59+
warning C5274: behavior change: _Alignas no longer applies to the type '<unnamed-tag>' (only applies to declared data objects)
60+
warning C5273: behavior change: _Alignas on anonymous type no longer ignored (promoted members will align)
61+
```
62+
63+
If you want the earlier behavior, replace `_Alignas(N)` with `__declspec(align(N))`. Unlike `_Alignas`, `declspec(align)` can be applied to a type.
64+
2465
### `__VA_OPT__` is enabled as an extension under `/Zc:preprocessor`
2566
2667
`__VA_OPT__` was added to C++20 and C23. Previous to its addition, there wasn't a standard way to elide a comma in a variadic macro. To provide better backward compatibility, `__VA_OPT__` is enabled under the token based preprocessor `/Zc:preprocessor` across all language versions.
@@ -293,7 +334,7 @@ enum Enum {
293334
static_assert(B == 1); // previously failed, now succeeds under /Zc:enumTypes
294335
```
295336

296-
In this example the enumerator `A` should have type **`char`** prior to the closing brace of the enumeration, so `B` should be initialized using `sizeof(char)`. Before the **`/Zc:enumTypes`** fix, `A` had enumeration type `Enum` with a deduced underlying type **`int`**, and `B` was initialized using `sizeof(Enum)`, or 4.
337+
In this example the enumerator `A` should have type **`char`** before the closing brace of the enumeration, so `B` should be initialized using `sizeof(char)`. Before the **`/Zc:enumTypes`** fix, `A` had enumeration type `Enum` with a deduced underlying type **`int`**, and `B` was initialized using `sizeof(Enum)`, or 4.
297338

298339
## <a name="improvements_173"></a> Conformance improvements in Visual Studio 2022 version 17.3
299340

0 commit comments

Comments
 (0)