Skip to content

Commit ebbc18a

Browse files
TaojunshenSteve WishnouskyatikmapariColin RobertsonPRMerger19
authored
4/8/2022 AM Publish (#4212)
* Update open-wopen.md Clarify that _O_TEMPORARY sets FILE_SHARE_DELETE. * Update other pages that mention _O_TEMPORARY effects. * Broken link fixed * Broken link fixed * Update virtual-functions.md * Address cpp-docs 3780 3782 3790 3791 3805 * Attempt correction of table format * Add documentation for compiler error C2956 and update error text (MicrosoftDocs#4176) * Add documentation for compiler error C2956 and update error text * Add TOC entry * Update for grammar and my own comprehension. Sometimes, you just get carried away. This version could use some simplification. * Simplify. Address remarks, attempt simplification. Acrolinx all the things. * More updates per review Co-authored-by: Colin Robertson <corob@microsoft.com> * Address cpp-docs 3816 * Address non-blocking issues from 4207 * fix for sample program. Co-authored-by: Steve Wishnousky <stwish@microsoft.com> Co-authored-by: atikmapari <31974726+atikmapari@users.noreply.github.com> Co-authored-by: Colin Robertson <corob@microsoft.com> Co-authored-by: PRMerger19 <prmrgr19@microsoft.com> Co-authored-by: Ming Ho <94572161+homing1@users.noreply.github.com> Co-authored-by: PRMerger5 <prmergr5@microsoft.com> Co-authored-by: Regan Downer <97987445+v-regandowner@users.noreply.github.com> Co-authored-by: Jonathan Emmett <joemmett@microsoft.com> Co-authored-by: Tamara K <93546702+tamarakhader@users.noreply.github.com> Co-authored-by: TylerMSFT <Tyler.Whitney@microsoft.com> Co-authored-by: PRMerger17 <prmrgr17@microsoft.com>
1 parent 7bce43f commit ebbc18a

12 files changed

+147
-59
lines changed

docs/build/arm64-exception-handling.md

Lines changed: 25 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,39 +11,41 @@ Windows on ARM64 uses the same structured exception handling mechanism for async
1111

1212
The exception unwinding data conventions, and this description, are intended to:
1313

14-
1. Provide enough description to allow unwinding without code probing in all cases.
14+
- Provide enough description to allow unwinding without code probing in all cases.
1515

16-
- Analyzing the code requires the code to be paged in. It prevents unwinding in some circumstances where it's useful (tracing, sampling, debugging).
16+
- Analyzing the code requires the code to be paged in. It prevents unwinding in some circumstances where it's useful (tracing, sampling, debugging).
1717

18-
- Analyzing the code is complex; the compiler must be careful to only generate instructions that the unwinder can decode.
1918

20-
- If unwinding can't be fully described by using unwind codes, then in some cases it must fall back to instruction decoding. Instruction decoding increases the overall complexity, and ideally should be avoided.
19+
- Analyzing the code is complex; the compiler must be careful to only generate instructions that the unwinder can decode.
2120

22-
1. Support unwinding in mid-prolog and mid-epilog.
21+
- If unwinding can't be fully described by using unwind codes, then in some cases it must fall back to instruction decoding. Instruction decoding increases the overall complexity, and ideally should be avoided.
2322

24-
- Unwinding is used in Windows for more than exception handling. It's critical that code can unwind accurately even when in the middle of a prolog or epilog code sequence.
2523

26-
1. Take up a minimal amount of space.
24+
- Support unwinding in mid-prolog and mid-epilog.
2725

28-
- The unwind codes must not aggregate to significantly increase the binary size.
26+
- Unwinding is used in Windows for more than exception handling. It's critical that code can unwind accurately even when in the middle of a prolog or epilog code sequence.
2927

30-
- Since the unwind codes are likely to be locked in memory, a small footprint ensures a minimal overhead for each loaded binary.
28+
- Take up a minimal amount of space.
29+
30+
- The unwind codes must not aggregate to significantly increase the binary size.
31+
32+
- Since the unwind codes are likely to be locked in memory, a small footprint ensures a minimal overhead for each loaded binary.
3133

3234
## Assumptions
3335

3436
These assumptions are made in the exception handling description:
3537

36-
1. Prologs and epilogs tend to mirror each other. By taking advantage of this common trait, the size of the metadata needed to describe unwinding can be greatly reduced. Within the body of the function, it doesn't matter whether the prolog's operations are undone, or the epilog's operations are done in a forward manner. Both should produce identical results.
38+
- Prologs and epilogs tend to mirror each other. By taking advantage of this common trait, the size of the metadata needed to describe unwinding can be greatly reduced. Within the body of the function, it doesn't matter whether the prolog's operations are undone, or the epilog's operations are done in a forward manner. Both should produce identical results.
3739

38-
1. Functions tend on the whole to be relatively small. Several optimizations for space rely on this fact to achieve the most efficient packing of data.
40+
- Functions tend on the whole to be relatively small. Several optimizations for space rely on this fact to achieve the most efficient packing of data.
3941

40-
1. There's no conditional code in epilogs.
42+
- There's no conditional code in epilogs.
4143

42-
1. Dedicated frame pointer register: If the sp is saved in another register (x29) in the prolog, that register remains untouched throughout the function. It means the original sp may be recovered at any time.
44+
- Dedicated frame pointer register: If the sp is saved in another register (x29) in the prolog, that register remains untouched throughout the function. It means the original sp may be recovered at any time.
4345

44-
1. Unless the sp is saved in another register, all manipulation of the stack pointer occurs strictly within the prolog and epilog.
46+
- Unless the sp is saved in another register, all manipulation of the stack pointer occurs strictly within the prolog and epilog.
4547

46-
1. The stack frame layout is organized as described in the next section.
48+
- The stack frame layout is organized as described in the next section.
4749

4850
## ARM64 stack frame layout
4951

@@ -275,11 +277,13 @@ The array of unwind codes is a pool of sequences that describe exactly how to un
275277

276278
If exceptions were guaranteed to only ever occur within a function body, and never within a prolog or any epilog, then only a single sequence would be necessary. However, the Windows unwinding model requires that code can unwind from within a partially executed prolog or epilog. To meet this requirement, the unwind codes have been carefully designed so they unambiguously map 1:1 to each relevant opcode in the prolog and epilog. This design has several implications:
277279

278-
1. By counting the number of unwind codes, it's possible to compute the length of the prolog and epilog.
279280

280-
1. By counting the number of instructions past the start of an epilog scope, it's possible to skip the equivalent number of unwind codes. We can execute the rest of a sequence to complete the partially executed unwind done by the epilog.
281+
- By counting the number of unwind codes, it's possible to compute the length of the prolog and epilog.
282+
283+
- By counting the number of instructions past the start of an epilog scope, it's possible to skip the equivalent number of unwind codes. We can execute the rest of a sequence to complete the partially executed unwind done by the epilog.
284+
285+
- By counting the number of instructions before the end of the prolog, it's possible to skip the equivalent number of unwind codes. We can execute the rest of the sequence to undo only those parts of the prolog that have completed execution.
281286

282-
1. By counting the number of instructions before the end of the prolog, it's possible to skip the equivalent number of unwind codes. We can execute the rest of the sequence to undo only those parts of the prolog that have completed execution.
283287

284288
The unwind codes are encoded according to the table below. All unwind codes are a single/double byte, except the one that allocates a huge stack. There are 21 unwind codes in total. Each unwind code maps exactly one instruction in the prolog/epilog, to allow for unwinding of partially executed prologs and epilogs.
285289

@@ -365,7 +369,7 @@ Step 4: Save input arguments in the home parameter area.
365369

366370
Step 5: Allocate remaining stack, including local area, \<x29,lr> pair, and outgoing parameter area. 5a corresponds to canonical type 1. 5b and 5c are for canonical type 2. 5d and 5e are for both type 3 and type 4.
367371

368-
| Step # | Flag values | # of instructions | Opcode | Unwind Code |
372+
| Step # | Flag values | # of instructions | Opcode | Unwind code |
369373
|--|--|--|--|--|
370374
| 0 | | | `#intsz = RegI * 8;`<br/>`if (CR==01) #intsz += 8; // lr`<br/>`#fpsz = RegF * 8;`<br/>`if(RegF) #fpsz += 8;`<br/>`#savsz=((#intsz+#fpsz+8*8*H)+0xf)&~0xf)`<br/>`#locsz = #famsz - #savsz` |
371375
| 1 | 0 < **RegI** <= 10 | **RegI** / 2 +<br/> **RegI** % 2 | `stp x19,x20,[sp,#savsz]!`<br/>`stp x21,x22,[sp,#16]`<br/>`...` | `save_regp_x`<br/>`save_regp`<br/>`...` |
@@ -624,5 +628,5 @@ Epilog Start Index [4] points to the middle of Prolog unwind code (partially reu
624628

625629
## See also
626630

627-
[Overview of ARM64 ABI conventions](arm64-windows-abi-conventions.md)<br/>
628-
[ARM Exception Handling](arm-exception-handling.md)
631+
[Overview of ARM64 ABI conventions](arm64-windows-abi-conventions.md)\
632+
[ARM exception handling](arm-exception-handling.md)

docs/c-language/c-operators.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
---
2-
description: "Learn more about: C Operators"
3-
title: "C Operators"
4-
ms.date: "06/14/2018"
2+
description: "Learn more about: C operators"
3+
title: "C operators"
4+
ms.date: 04/07/2022
55
helpviewer_keywords: ["ternary operators", "operators [C]", "symbols, operators", "binary operators", "associativity of operators", "binary data, binary expressions"]
66
ms.assetid: 13bc4c8e-2dc9-4b23-9f3a-25064e8777ed
77
---
8-
# C Operators
8+
# C operators
99

1010
The C operators are a subset of the [C++ built-in operators](../cpp/cpp-built-in-operators-precedence-and-associativity.md).
1111

12-
There are three types of operators. A unary expression consists of either a unary operator followed by an operand, or the **`sizeof`** keyword followed by an expression. The expression can be either the name of a variable or a cast expression. If the expression is a cast expression, it must be enclosed in parentheses. A binary expression consists of two operands joined by a binary operator. A ternary expression consists of three operands joined by the conditional-expression operator.
12+
13+
There are three types of operators. A unary expression consists of either a unary operator followed by an operand, or the **`sizeof`** or **`_Alignof`** keyword followed by an expression. The expression can be either the name of a variable or a cast expression. If the expression is a cast expression, it must be enclosed in parentheses. A binary expression consists of two operands joined by a binary operator. A ternary expression consists of three operands joined by the conditional-expression operator.
14+
1315

1416
C includes the following unary operators:
1517

docs/c-runtime-library/reference/open-wopen.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ The **`_open`** function opens the file specified by *`filename`* and prepares i
7272
| **`_O_BINARY`** | Opens the file in binary (untranslated) mode. (See [`fopen`](fopen-wfopen.md) for a description of binary mode.) |
7373
| **`_O_CREAT`** | Creates a file and opens it for writing. Has no effect if the file specified by *filename* exists. The *pmode* argument is required when **`_O_CREAT`** is specified. |
7474
| **`_O_CREAT`** &#124; **`_O_SHORT_LIVED`** | Creates a file as temporary and if possible does not flush to disk. The *pmode* argument is required when **`_O_CREAT`** is specified. |
75-
| **`_O_CREAT`** &#124; **`_O_TEMPORARY`** | Creates a file as temporary; the file is deleted when the last file descriptor is closed. The *pmode* argument is required when **`_O_CREAT`** is specified. |
75+
| **`_O_CREAT`** &#124; **`_O_TEMPORARY`** | Creates a file as temporary; the file is deleted when the last file descriptor is closed. The *pmode* argument is required when **`_O_CREAT`** is specified. To preserve legacy behavior for app-compatibility, other processes are not prevented from deleting this file. |
7676
| **`_O_CREAT`** &#124; `_O_EXCL` | Returns an error value if a file specified by *filename* exists. Applies only when used with **`_O_CREAT`**. |
7777
| **`_O_NOINHERIT`** | Prevents creation of a shared file descriptor. |
7878
| **`_O_RANDOM`** | Specifies that caching is optimized for, but not restricted to, random access from disk. |

docs/c-runtime-library/reference/sopen-s-wsopen-s.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ The integer expression *oflag* is formed by combining one or more manifest const
8888
| **`_O_BINARY`** | Opens the file in binary (untranslated) mode. (See [`fopen`](fopen-wfopen.md) for a description of binary mode.) |
8989
| **`_O_CREAT`** | Creates a file and opens it for writing. Has no effect if the file specified by *`filename`* exists. The *`pmode`* argument is required when **`_O_CREAT`** is specified. |
9090
| **`_O_CREAT`** &#124; **`_O_SHORT_LIVED`** | Creates a file as temporary and if possible does not flush to disk. The *`pmode`* argument is required when **`_O_CREAT`** is specified. |
91-
| **`_O_CREAT`** &#124; **`_O_TEMPORARY`** | Creates a file as temporary; the file is deleted when the last file descriptor is closed. The *`pmode`* argument is required when **`_O_CREAT`** is specified. |
91+
| **`_O_CREAT`** &#124; **`_O_TEMPORARY`** | Creates a file as temporary; the file is deleted when the last file descriptor is closed. The *`pmode`* argument is required when **`_O_CREAT`** is specified. To preserve legacy behavior for app-compatibility, other processes are not prevented from deleting this file. |
9292
| **`_O_CREAT`** &#124; `_O_EXCL` | Returns an error value if a file specified by *`filename`* exists. Applies only when used with **`_O_CREAT`**. |
9393
| **`_O_NOINHERIT`** | Prevents creation of a shared file descriptor. |
9494
| **`_O_RANDOM`** | Specifies that caching is optimized for, but not restricted to, random access from disk. |

docs/c-runtime-library/reference/sopen-wsopen.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ The integer expression *oflag* is formed by combining one or more of the followi
8181
| **_O_BINARY** | Opens the file in binary (untranslated) mode. (See [fopen](fopen-wfopen.md) for a description of binary mode.) |
8282
| **_O_CREAT** | Creates a file and opens it for writing. Has no effect if the file specified by *filename* exists. The *pmode* argument is required when **_O_CREAT** is specified. |
8383
| **_O_CREAT** &#124; **_O_SHORT_LIVED** | Creates a file as temporary and if possible does not flush to disk. The *pmode* argument is required when **_O_CREAT** is specified. |
84-
| **_O_CREAT** &#124; **_O_TEMPORARY** | Creates a file as temporary; the file is deleted when the last file descriptor is closed. The *pmode* argument is required when **_O_CREAT** is specified. |
84+
| **_O_CREAT** &#124; **_O_TEMPORARY** | Creates a file as temporary; the file is deleted when the last file descriptor is closed. The *pmode* argument is required when **_O_CREAT** is specified. To preserve legacy behavior for app-compatibility, other processes are not prevented from deleting this file. |
8585
| **_O_CREAT** &#124; `_O_EXCL` | Returns an error value if a file specified by *filename* exists. Applies only when used with **_O_CREAT**. |
8686
| **_O_NOINHERIT** | Prevents creation of a shared file descriptor. |
8787
| **_O_RANDOM** | Specifies that caching is optimized for, but not restricted to, random access from disk. |
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
description: "Learn more about: Compiler Error C2956"
3+
title: "Compiler Error C2956"
4+
ms.date: 04/05/2022
5+
f1_keywords: ["C2956"]
6+
helpviewer_keywords: ["C2956"]
7+
---
8+
# Compiler Error C2956
9+
10+
> usual deallocation function '*function*' would be chosen as placement deallocation function
11+
12+
The deallocation function found for the placement new expression matches one of the usual deallocation functions. Either an implicit compiler-generated deallocation or an explicit `delete` (or `delete[]`) would use the wrong deallocation function.
13+
14+
## Remarks
15+
16+
Error C2956 indicates you used a *placement new expression* (a `new` expression that takes parameters) in a way that can cause a memory leak or runtime crash. It usually means the resulting value can't be deleted in a typical way. That is, either an explicit `delete` (or `delete[]`) expression in your code, or the implicit deallocation when a constructor throws an exception, could invoke the wrong `operator delete` or supply it with the wrong parameters.
17+
18+
The C++ standard specifies *usual deallocation functions* as overloads of `operator delete` or `operator delete[]` that take extra parameters of type `std::size_t` (C++14 or later), `std::align_val_t` (C++17 or later), and `std::destroying_delete_t` (C++20 or later). When you use a placement new expression, the compiler looks for a matching `operator delete` function that takes the same parameters (after the first one). If one is found and its signature matches a usual deallocation function, the compiler reports error C2956.
19+
20+
The way to resolve the issue depends in part on your intent. For example, in C++ 11, you could define an `operator new` overload that takes an extra `size_t` parameter in your class to pass a value to the allocator. In C++ 14, the same code now causes an error:
21+
22+
```cpp
23+
#include <new>
24+
struct T {
25+
void* operator new(std::size_t, std::size_t); // Placement allocation function
26+
void operator delete(void*, std::size_t); // now considered a usual deallocation function
27+
};
28+
29+
T* p = new (0) T; // error: usual deallocation function would be chosen as placement deallocation function
30+
```
31+
32+
If your intent is to specify over-aligned memory for an object, you can instead specify the alignment directly on the type by using `alignas`. For more information about `alignas`, see [Alignment](../../cpp/alignment-cpp-declarations.md).
33+
34+
If your intent is to specify over-aligned memory for a heap-allocated native type or an array, wrap it in a `struct` or `class` that has the `alignas` specifier. Then normal `new` and `delete` expressions can allocate and deallocate instances that have your intended alignment.
35+
36+
## Example
37+
38+
In this example, the *`new-expression`* uses placement syntax with an argument of type `std::align_val_t`. However, since type `T` doesn't specify an alignment requirement, a *`delete-expression`* on a `T*` won't invoke a matching over-aligned deallocation function. Instead, the compiler would invoke the usual deallocation function `void operator delete(void* ptr) noexcept`, which doesn't handle an over-aligned allocation. Rather than cause a crash or a memory leak, the compiler reports an error for this use of placement `new`:
39+
40+
```cpp
41+
#include <new>
42+
struct T {};
43+
44+
int main()
45+
{
46+
T* p = new (std::align_val_t{64}) T; // C2956
47+
delete p; // ordinary, not over-aligned delete
48+
}
49+
```
50+
51+
To resolve this issue, apply an `alignas` specifier to `T`:
52+
53+
```cpp
54+
#include <new>
55+
struct alignas(64) T {};
56+
57+
int main()
58+
{
59+
T* p = new T; // invokes ::operator new(std::size_t, std::align_val_t)
60+
delete p; // now invokes ::operator delete(void*, std::align_val_t)
61+
}
62+
```

docs/error-messages/compiler-errors-2/compiler-errors-c2900-through-c3499.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ The articles in this section of the documentation explain a subset of the error
7272
|[Compiler error C2953](compiler-error-c2953.md)|'*type*': class template has already been defined|
7373
|Compiler error C2954|instruction word argument not in range|
7474
|[Compiler error C2955](compiler-error-c2955.md)|'*type*': use of class template/generic requires template/generic argument list|
75-
|Compiler error C2956|sized deallocation function 'operator delete(void*, size_t)' would be chosen as placement deallocation function.|
75+
|[Compiler error C2956](compiler-error-c2956.md)|usual deallocation function '*function*' would be chosen as placement deallocation function|
7676
|[Compiler error C2957](compiler-error-c2957.md)|'*token*': invalid left delimiter: expected '<'|
7777
|[Compiler error C2958](compiler-error-c2958.md)|the left *delimiter* found at '*file*(*line_number*)' was not matched correctly|
7878
|[Compiler error C2959](compiler-error-c2959.md)|a generic class or function may not be a member of a template|

docs/error-messages/toc.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,6 +1915,8 @@ items:
19151915
href: compiler-errors-2/compiler-error-c2953.md
19161916
- name: Compiler error C2955
19171917
href: compiler-errors-2/compiler-error-c2955.md
1918+
- name: Compiler error C2956
1919+
href: compiler-errors-2/compiler-error-c2956.md
19181920
- name: Compiler error C2957
19191921
href: compiler-errors-2/compiler-error-c2957.md
19201922
- name: Compiler error C2958

0 commit comments

Comments
 (0)