Skip to content

Commit 67bab3e

Browse files
authored
Merge pull request #3102 from stwish-msft/patch-1
Clarify assert behavior
2 parents 7b6f99a + b8a74ee commit 67bab3e

File tree

1 file changed

+22
-11
lines changed

1 file changed

+22
-11
lines changed

docs/c-runtime-library/reference/assert-macro-assert-wassert.md

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
---
22
title: "assert Macro, _assert, _wassert"
3+
description: "The effects of the assert macros and functions in the C Runtime."
34
ms.date: "11/04/2016"
45
api_name: ["assert", "_assert", "_wassert"]
56
api_location: ["msvcrt.dll", "msvcr80.dll", "msvcr90.dll", "msvcr100.dll", "msvcr100_clr0400.dll", "msvcr110.dll", "msvcr110_clr0400.dll", "msvcr120.dll", "msvcr120_clr0400.dll", "ucrtbase.dll", "api-ms-win-crt-runtime-l1-1-0.dll"]
@@ -47,33 +48,43 @@ The line number in the source file of the failed assertion.
4748

4849
## Remarks
4950

50-
The **assert** macro is typically used to identify logic errors during program development. Use it to stop program execution when unexpected conditions occur by implementing the *expression* argument to evaluate to **`false`** only when the program is operating incorrectly. Assertion checks can be turned off at compile time by defining the macro **NDEBUG**. You can turn off the **assert** macro without modifying your source files by using a **/DNDEBUG** command-line option. You can turn off the **assert** macro in your source code by using a `#define NDEBUG` directive before \<assert.h> is included.
51+
The `assert` macro is typically used to identify logic errors during program development. Use it to stop program execution when unexpected conditions occur by implementing the *expression* argument to evaluate to **`false`** only when the program is operating incorrectly. Assertion checks can be turned off at compile time by defining the macro **NDEBUG**. You can turn off the `assert` macro without modifying your source files by using a **/DNDEBUG** command-line option. You can turn off the `assert` macro in your source code by using a `#define NDEBUG` directive before \<assert.h> is included.
5152

52-
The **assert** macro prints a diagnostic message when *expression* evaluates to **`false`** (0) and calls [abort](abort.md) to terminate program execution. No action is taken if *expression* is **`true`** (nonzero). The diagnostic message includes the failed expression, the name of the source file and line number where the assertion failed.
53+
The `assert` macro prints a diagnostic message when *expression* evaluates to **`false`** (0) and calls [`abort`](abort.md) to stop program execution. No action is taken if *expression* is **`true`** (nonzero). The diagnostic message includes the failed expression, the name of the source file and line number where the assertion failed.
5354

54-
The diagnostic message is printed in wide characters. Thus, it will work as expected even if there are Unicode characters in the expression.
55+
The diagnostic message is printed in wide (`wchar_t`) characters. Therefore, it will work as expected even if there are Unicode characters in the expression.
5556

56-
The destination of the diagnostic message depends on the type of application that called the routine. Console applications always receive the message through **stderr**. In a Windows-based application, **assert** calls the Windows [MessageBox](/windows/win32/api/winuser/nf-winuser-messagebox) function to create a message box to display the message along with an **OK** button. When the user clicks **OK**, the program aborts immediately.
57+
The destination of the diagnostic message depends on the type of application that called the routine. Console applications receive the message through **stderr**. In a Windows-based application, `assert` calls the Windows [MessageBox](/windows/win32/api/winuser/nf-winuser-messagebox) function to create a message box to display the message with three buttons: **Abort**, **Retry**, and **Ignore**. If the user clicks **Abort**, the program aborts immediately. If the user clicks **Retry**, the debugger is called and the user can debug the program if just-in-time (JIT) debugging is enabled. If the user clicks **Ignore**, the program will continue with normal execution. Clicking **Ignore** when an error condition exists can result in undefined behavior since preconditions of the calling code weren't met.
5758

58-
When the application is linked with a debug version of the run-time libraries, **assert** creates a message box with three buttons: **Abort**, **Retry**, and **Ignore**. If the user clicks **Abort**, the program aborts immediately. If the user clicks **Retry**, the debugger is called and the user can debug the program if just-in-time (JIT) debugging is enabled. If the user clicks **Ignore**, **assert** continues with its normal execution: creating the message box with the **OK** button. Note that clicking **Ignore** when an error condition exists can result in undefined behavior.
59+
To override the default output behavior regardless of the app type, call [`_set_error_mode`](set-error-mode.md) to select between the output-to-stderr and display-dialog-box behavior.
60+
61+
After `assert` displays its message, it calls [`abort`](abort.md), which displays a dialog box with **Abort**, **Retry**, and **Ignore** buttons. [`abort`](abort.md) exits the program, so the **Retry** and **Ignore** button won't resume program execution following the `assert` call. If `assert` displayed a dialog box, the [`abort`](abort.md) dialog box isn't shown. The only time the [`abort`](abort.md) dialog box is shown is when `assert` sends its output to stderr.
62+
63+
As a consequence of the above behavior, a dialog box is always displayed following an `assert` call in debug mode. The behavior of each button is captured in the below table.
64+
65+
|Error mode|Output to stderr (Console/_OUT_TO_STDERR)|Display Dialog Box (Windows/_OUT_TO_MSGBOX)|
66+
|----------|----------------|------------------|
67+
|Abort|Exit immediately with exit code 3|Exit immediately with exit code 3|
68+
|Retry|Break into debugger during `abort`|Break into debugger during `assert`|
69+
|Ignore|Finish exiting via `abort`|Continue program as though the assert didn't fire (may result in undefined behavior since preconditions of the calling code weren't met)|
5970

6071
For more information about CRT debugging, see [CRT Debugging Techniques](/visualstudio/debugger/crt-debugging-techniques).
6172

62-
The **_assert** and **_wassert** functions are internal CRT functions. They help minimize the code required in your object files to support assertions. We do not recommend that you call these functions directly.
73+
The `_assert` and `_wassert` functions are internal CRT functions. They help minimize the code required in your object files to support assertions. We don't recommend that you call these functions directly.
6374

64-
The **assert** macro is enabled in both the release and debug versions of the C run-time libraries when **NDEBUG** is not defined. When **NDEBUG** is defined, the macro is available but does not evaluate its argument and has no effect. When it is enabled, the **assert** macro calls **_wassert** for its implementation. Other assertion macros, [_ASSERT](assert-asserte-assert-expr-macros.md), [_ASSERTE](assert-asserte-assert-expr-macros.md) and [_ASSERT_EXPR](assert-asserte-assert-expr-macros.md), are also available, but they only evaluate the expressions passed to them when the [_DEBUG](../../c-runtime-library/debug.md) macro has been defined and when they are in code linked with the debug version of the C run-time libraries.
75+
The `assert` macro is enabled in both the release and debug versions of the C run-time libraries when **NDEBUG** isn't defined. When **NDEBUG** is defined, the macro is available but doesn't evaluate its argument and has no effect. When it's enabled, the `assert` macro calls `_wassert` for its implementation. Other assertion macros, [_ASSERT](assert-asserte-assert-expr-macros.md), [_ASSERTE](assert-asserte-assert-expr-macros.md) and [_ASSERT_EXPR](assert-asserte-assert-expr-macros.md), are also available, but they only evaluate the expressions passed to them when the [_DEBUG](../../c-runtime-library/debug.md) macro has been defined and when they are in code linked with the debug version of the C run-time libraries.
6576

6677
## Requirements
6778

6879
|Routine|Required header|
6980
|-------------|---------------------|
70-
|**assert**, **_wassert**|\<assert.h>|
81+
|`assert`, `_wassert`|\<assert.h>|
7182

72-
The signature of the **_assert** function is not available in a header file. The signature of the **_wassert** function is only available when the **NDEBUG** macro is not defined.
83+
The signature of the `_assert` function isn't available in a header file. The signature of the `_wassert` function is only available when the **NDEBUG** macro isn't defined.
7384

7485
## Example
7586

76-
In this program, the **analyze_string** function uses the **assert** macro to test several conditions related to string and length. If any of the conditions fails, the program prints a message indicating what caused the failure.
87+
In this program, the **analyze_string** function uses the `assert` macro to test several conditions related to string and length. If any of the conditions fails, the program prints a message indicating what caused the failure.
7788

7889
```C
7990
// crt_assert.c
@@ -114,7 +125,7 @@ Analyzing string '(null)'
114125
Assertion failed: string != NULL, file crt_assert.c, line 25
115126
```
116127

117-
After the assertion failure, depending on the version of the operating system and run-time library, you may see a message box that contains something like the following:
128+
After the assertion failure, depending on the version of the operating system and run-time library, you may see a message box that contains something similar to:
118129

119130
```Output
120131
A problem caused the program to stop working correctly. Windows will close the program and notify you if a solution is available.

0 commit comments

Comments
 (0)