Skip to content

Fix multiple issues with warning wave docs #46487

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

Merged
merged 1 commit into from
May 30, 2025
Merged
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
<PropertyGroup>
<ImplicitUsings>enable</ImplicitUsings>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningLevel>8</WarningLevel>
<WarningLevel>9</WarningLevel>
<AnalysisLevel>preview</AnalysisLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: "Compiler warning waves"
description: "C# warning waves are optional warnings that can be reported on code where previously a warning wouldn't have been reported. They represent practices that could be harmful, or potentially elements that might be breaking changes in the future."
ms.date: 07/01/2024
description: "C# warning waves are optional warnings that can be reported on code where previously a warning isn't reported. They represent practices that could be harmful, or potentially elements that might be breaking changes in the future."
ms.date: 05/29/2025
f1_keywords:
- "CS7023"
- "CS8073"
Expand Down Expand Up @@ -39,7 +39,17 @@ helpviewer_keywords:
---
# C# Warning waves

New warnings and errors can be introduced in each release of the C# compiler. When new warnings could be reported on existing code, those warnings are introduced under an opt-in system referred to as a *warning wave*. The opt-in system means that you shouldn't see new warnings on existing code without taking action to enable them. Warning waves are enabled using the [**AnalysisLevel**](../compiler-options/errors-warnings.md#analysis-level) element in your project file. When `<TreatWarningsAsErrors>true</TreatWarningsAsErrors>` is specified, enabled warning wave warnings generate errors. Warning wave 5 diagnostics were added in C# 9. Warning wave 6 diagnostics were added in C# 10. Warning wave 7 diagnostics were added in C# 11. Warning wave 8 diagnostics were added in C# 12.
New warnings and errors can be introduced in each release of the C# compiler. When new warnings could be reported on existing code, those warnings are introduced under an opt-in system referred to as a *warning wave*. The opt-in system means that you shouldn't see new warnings on existing code without taking action to enable them. When `<TreatWarningsAsErrors>true</TreatWarningsAsErrors>` is specified, enabled warning wave warnings generate errors. Warning wave 5 diagnostics were added in C# 9. Warning wave 6 diagnostics were added in C# 10. Warning wave 7 diagnostics were added in C# 11. Warning wave 8 diagnostics were added in C# 12. Warning wave 9 diagnostics were added in C# 13.

Beginning with the .NET 7 SDK (C# 11), the build system sets warning waves with the following rules:

- AnalysisLevel tracks the current TFM if not specified
- AnalysisLevel is set to latest if the current TFM is the 'latest' TFM (as defined by a property that we need to bump)
- WarningLevel should track the current TFM if not specified
- WarningLevel shouldn't override the user-provided value
- WarningLevel should be set to 4 if the project is a .NET Framework project

For SDKs earlier than .NET 7, AnalysisLevel always overwrote WarningLevel.

## CS9123 - Taking address of local or parameter in async method can create a GC hole.

Expand All @@ -50,8 +60,6 @@ The following code produces CS9123:

:::code language="csharp" source="./snippets/WarningWaves/WaveEight.cs" id="NoAmpersand":::

Beginning with C# 13, this code generates a compiler error.

## CS8981 - The type name only contains lower-cased ascii characters.

*Warning wave 7*
Expand Down Expand Up @@ -127,7 +135,7 @@ The following examples show the warnings generated from the improved definite as

- CS8880: Auto-implemented property 'Property' must be fully assigned before control is returned to the caller.
- CS8881: Field 'field' must be fully assigned before control is returned to the caller.
- CS8882: The out parameter 'parameter' must be assigned to before control leaves the current method.
- CS8882: The `out` parameter 'parameter' must be assigned to before control leaves the current method.
- CS8883: Use of possibly unassigned auto-implemented property 'Property'.
- CS8884: Use of possibly unassigned field 'Field'
- CS8885: The 'this' object can't be used before all its fields have been assigned.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
description: "C# Compiler Options for errors and warnings. These options suppress or enable warnings, and control warnings as errors."
title: "Compiler Options - errors and warnings"
ms.date: 10/30/2023
ms.date: 05/30/2025
f1_keywords:
- "cs.build.options"
helpviewer_keywords:
Expand All @@ -23,15 +23,15 @@ The following options control how the compiler reports errors and warnings.
| `WarningLevel` | `-warn` | Set warning level. [More info.](#warninglevel) |
| `AnalysisLevel` | / | Set optional warning level. [More info.](#analysis-level) |
| `TreatWarningsAsErrors` | `-warnaserror` | Treat all warnings as errors. [More info.](#treatwarningsaserrors) |
| `WarningsAsErrors` | `-warnaserror` | Treat one or more warnings as errors. [More info.](#warningsaserrors-and-warningsnotaserrors) |
| `WarningsNotAsErrors` | `-warnnotaserror` | Treat one or more warnings not as errors. [More info.](#warningsaserrors-and-warningsnotaserrors) |
| `WarningsAsErrors` | `-warnaserror+` | Treat one or more warnings as errors. [More info.](#warningsaserrors-and-warningsnotaserrors) |
| `WarningsNotAsErrors` | `-warnaserror-` | Treat one or more warnings not as errors. [More info.](#warningsaserrors-and-warningsnotaserrors) |
| `NoWarn` | `-nowarn` | Set a list of disabled warnings. [More info.](#nowarn) |
| `CodeAnalysisRuleSet` | `-ruleset` | Specify a ruleset file that disables specific diagnostics. [More info.](#codeanalysisruleset) |
| `ErrorLog` | `-errorlog` | Specify a file to log all compiler and analyzer diagnostics. [More info.](#errorlog) |
| `ReportAnalyzer` | `-reportanalyzer` | Report additional analyzer information, such as execution time. [More info.](#reportanalyzer) |
| `ReportAnalyzer` | `-reportanalyzer` | Report extra analyzer information, such as execution time. [More info.](#reportanalyzer) |

> [!NOTE]
> Refer to [Compiler options](index.md#how-to-set-options) for more information on configuring these options for your project.
> For more information about configuring these options for your project, see the [Compiler options](index.md#how-to-set-options). For more information on the available switches, see the [MSBuild command line switches](/visualstudio/msbuild/msbuild-command-line-reference#switches) article in the Visual Studio documentation.

## WarningLevel

Expand All @@ -52,13 +52,21 @@ The element value is the warning level you want displayed for the compilation: L
| 4 (default) | Displays all level 3 warnings plus informational warnings. |

> [!WARNING]
> The compiler command line accepts values greater than 4 to enable [warning wave warnings](../compiler-messages/warning-waves.md). However, the .NET SDK sets the *WarningLevel* to match the *AnalysisLevel* in your project file.
> The compiler command line accepts values greater than 4 to enable [warning wave warnings](../compiler-messages/warning-waves.md).

To get information about an error or warning, you can look up the error code in the [Help Index](/visualstudio/help-viewer/install-manage-local-content). For other ways to get information about an error or warning, see [C# Compiler Errors](../compiler-messages/index.md). Use [**TreatWarningsAsErrors**](#treatwarningsaserrors) to treat all warnings as errors. Use [**DisabledWarnings**](#nowarn) to disable certain warnings.

## Analysis level

The **AnalysisLevel** option specifies additional [warning waves](../compiler-messages/warning-waves.md) and analyzers to enable. Warning wave warnings are additional checks that improve your code, or ensure it will be compatible with upcoming releases. Analyzers provide lint-like capability to improve your code.
The **AnalysisLevel** option specifies higher [warning waves](../compiler-messages/warning-waves.md) and analyzers to enable in .NET 7 and later projects. Warning wave warnings are extra checks that improve your code, or ensure it remains compatible with upcoming releases. Analyzers provide lint-like capability to improve your code.

Beginning with the .NET 7 SDK, **AnalysisLevel** and **WarningLevel** are set based on these rules:

- The default **AnalysisLevel** matches the Target Framework Moniker (TFM) from the project file.
- The default **WarningLevel** matches the value for **AnalysisLevel**.
- The default **WarningLevel** is 4 for .NET Framework projects.

Before the .NET 7 SDK, the **AnalysisLevel** overwrote the **WarningLevel**.

```xml
<AnalysisLevel>preview</AnalysisLevel>
Expand All @@ -85,7 +93,7 @@ The **TreatWarningsAsErrors** option treats all warnings as errors. You can also
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
```

All warning messages are instead reported as errors. The build process halts (no output files are built). By default, **TreatWarningsAsErrors** isn't in effect, which means warnings don't prevent the generation of an output file. Optionally, if you want only a few specific warnings to be treated as errors, you may specify a comma-separated list of warning numbers to treat as errors. The set of all nullability warnings can be specified with the [**Nullable**](language.md#nullable) shorthand. Use [**WarningLevel**](#warninglevel) to specify the level of warnings that you want the compiler to display. Use [**NoWarn**](#nowarn) to disable certain warnings.
All warning messages are instead reported as errors. The build process halts (no output files are built). By default, **TreatWarningsAsErrors** isn't in effect, which means warnings don't prevent the generation of an output file. Optionally, if you want only a few specific warnings to be treated as errors, you can specify a comma-separated list of warning numbers to treat as errors. The set of all nullability warnings can be specified with the [**Nullable**](language.md#nullable) shorthand. Use [**WarningLevel**](#warninglevel) to specify the level of warnings that you want the compiler to display. Use [**NoWarn**](#nowarn) to disable certain warnings.

> [!IMPORTANT]
> There are two subtle differences between using the `<TreatWarningsAsErrors>` element in your *csproj* file, and using the `warnaserror` MSBuild command line switch. *TreatWarningsAsErrors* only impacts the C# compiler, not any other MSBuild tasks in your *csproj* file. The `warnaserror` command line switch impacts all tasks. Secondly, the compiler doesn't produce any output on any warnings when *TreatWarningsAsErrors* is used. The compiler produces output when the `warnaserror` command line switch is used.
Expand All @@ -97,16 +105,16 @@ The **WarningsAsErrors** and **WarningsNotAsErrors** options override the **Trea
Enable warnings 0219, 0168, and all nullable warnings as errors:

```xml
<WarningsAsErrors>0219,CS0168,nullable</WarningsAsErrors>
<WarningsAsErrors>0219;CS0168;nullable</WarningsAsErrors>
```

Disable the same warnings as errors:

```xml
<WarningsNotAsErrors>0219,CS0168,nullable</WarningsNotAsErrors>
<WarningsNotAsErrors>0219;CS0168;nullable</WarningsNotAsErrors>
```

You use **WarningsAsErrors** to configure a set of warnings as errors. Use **WarningsNotAsErrors** to configure a set of warnings that should not be errors when you've set all warnings as errors.
You use **WarningsAsErrors** to configure a set of warnings as errors. Use **WarningsNotAsErrors** to configure a set of warnings that shouldn't be errors when you set all warnings as errors.

## NoWarn

Expand All @@ -116,20 +124,19 @@ The **NoWarn** option lets you suppress the compiler from displaying one or more
<NoWarn>warningnumber1,warningnumber2</NoWarn>
```

You need to specify only the numeric part of the warning identifier. For example, if you want to suppress *CS0028*, you could specify `<NoWarn>28</NoWarn>`. The compiler silently ignores warning numbers passed to **NoWarn** that were valid in previous releases, but that have been removed. For example, *CS0679* was valid in the compiler in Visual Studio .NET 2002 but was removed later.
You need to specify only the numeric part of the warning identifier. For example, if you want to suppress *CS0028*, you could specify `<NoWarn>28</NoWarn>`. The compiler silently ignores warning numbers passed to **NoWarn** that were valid in previous releases, but aren't generated by the current compiler. For example, *CS0679* was valid in the compiler in Visual Studio .NET 2002 but was removed later.

The following warnings can't be suppressed by the **NoWarn** option:

- Compiler Warning (level 1) CS2002
- Compiler Warning (level 1) CS2023
- Compiler Warning (level 1) CS2029

Note that warnings are intended to be an indication of a potential problem with your code, so you should understand the risks of disabling any particular warning. Use **NoWarn** only when you're certain that a warning is a false positive and can't possibly be a runtime bug.
Warnings are intended to be an indication of a potential problem with your code, so you should understand the risks of disabling any particular warning. Use **NoWarn** only when you're certain that a warning is a false positive and can't possibly be a runtime bug.

You might want to use a more targeted approach to disabling warnings:

- Most compilers provide ways to disable warnings just for certain lines of code, so that you can still review the warnings if they occur elsewhere in the same project. To suppress a warning only in a specific part of the code in C#, use [#pragma warning](../preprocessor-directives.md#pragma-warning).

- If your goal is to see more concise and focused output in your build log, you might want to change the build log verbosity. For more information, see [How to: View, save, and configure build log files](/visualstudio/ide/how-to-view-save-and-configure-build-log-files).

To add warning numbers to any previously set value for **NoWarn** without overwriting it, reference `$(NoWarn)` as shown in the following example:
Expand All @@ -156,7 +163,7 @@ Specify a file to log all compiler and analyzer diagnostics.
<ErrorLog>compiler-diagnostics.sarif</ErrorLog>
```

The **ErrorLog** option causes the compiler to output a [Static Analysis Results Interchange Format (SARIF) log](https://github.com/microsoft/sarif-tutorials/blob/main/docs/1-Introduction.md#:~:text=What%20is%20SARIF%3F,for%20use%20by%20simpler%20tools). SARIF logs are typically read by tools that analyze the results from compiler and analyzer diagnostics.
The **ErrorLog** option causes the compiler to output a [Static Analysis Results Interchange Format (SARIF) log](https://github.com/microsoft/sarif-tutorials/blob/main/docs/1-Introduction.md#:~:text=What%20is%20SARIF%3F,for%20use%20by%20simpler%20tools). Tools that analyze compiler and analyzer results read SARIF logs.

You can specify the SARIF format using the `version` argument to the `ErrorLog` element:

Expand All @@ -168,7 +175,7 @@ The separator can be either a comma (`,`) or a semicolon (`;`). Valid values for

## ReportAnalyzer

Report additional analyzer information, such as execution time.
Report extra analyzer information, such as execution time.

```xml
<ReportAnalyzer>true</ReportAnalyzer>
Expand All @@ -177,4 +184,4 @@ Report additional analyzer information, such as execution time.
The **ReportAnalyzer** option causes the compiler to emit extra MSBuild log information that details the performance characteristics of analyzers in the build. It's typically used by analyzer authors as part of validating the analyzer.

> [!IMPORTANT]
> The extra log information generated by this flag is only generated when the `-verbosity:detailed` command line option is used. See the [switches](/visualstudio/msbuild/msbuild-command-line-reference#switches) article in the MSBuild documentation for more information.
> The extra log information generated by this flag is only generated when the `-verbosity:detailed` command line option is used. For more information, see the [switches](/visualstudio/msbuild/msbuild-command-line-reference#switches) article in the MSBuild documentation.
Loading