Skip to content

Repo sync for protected CLA branch #3440

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 2 commits into from
Oct 8, 2021
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
71 changes: 71 additions & 0 deletions docs/ide/cpp-linter-overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---
description: "Learn more about: IntelliSense code linter for C++"
title: IntelliSense code linter for C++ overview
ms.date: 09/30/2021
ms.topic: conceptual
helpviewer_keywords:
- "C/C++, linter"
- "C++, linter"
- "IDE, linter"
- "IntelliSense, linter"
- "lightbulbs, linter"
- "suggested actions, linter"
monikerRange: ">=msvc-160"
---
# IntelliSense code linter for C++ overview

The IntelliSense code linter for C++ helps developers find and fix common C++ problems right inside Visual Studio. It's based on the same engine that provides C++ IntelliSense, so problems are flagged as soon as you type them.

![Animation showing the C++ linter in action.](../ide/media/linter-demo-animation.gif)

## Find problems

::: moniker range=">=msvc-170"

In Visual Studio 2019, the C++ linter is available as an option. Starting in Visual Studio 2022, the C++ Linter is enabled by default. To use it, just open a source file in the editor. The linter shows any problems it finds by annotations in the editor window and in the Error List window.

::: moniker-end
::: moniker range="msvc-160"

In Visual Studio 2019, the C++ linter is available as an option. To enable it, follow the instructions in [Configure the linter](#configure-the-linter). Then just open a source file in the editor. The linter shows any problems it finds by annotations in the editor window and in the Error List window.

::: moniker-end

## Fix problems

Most of the linter checks have suggestions for fixing the problem. Hover over the error squiggle and choose the light bulb that pops up to see the suggestions. A preview diff of the suggested change is shown, so you can confirm the change makes sense before you apply it.

## <a name="configure-the-linter"> Configure the linter

You can enable or disable the linter, or configure the severity level for each check, in the C++ Code Style options.

To change the linter options, on the menu bar, select **Tools** > **Options**. In the Options dialog, expand **Text Editor** > **C/C++** > **Code Style** > **Linter**.

By default, many of the checks have **Suggestion** severity so the Linter results aren't intrusive while you write code. You can set the severity to **Warning** or **Error**. Individual checks can be disabled by changing their severity to **None**.

When you change the check severity level, it changes how the problem is shown in the editor window and in the Error List window. Changes take effect for newly opened files.

::: moniker range=">=msvc-170"

![Screenshot that shows the C&#43;&#43; linter configuration.](../ide/media/linter-settings.png)

(The presentation in Visual Studio 2019 is slightly different, but the options are similar.)

::: moniker-end

## Known issues

::: moniker range=">=msvc-170"

- The **Comparison/Bitwise Precedence** check isn't available in the initial release of Visual Studio 2022, even though you can configure it in the Options dialog.

::: moniker-end
::: moniker range="msvc-160"

- The **Comparison/Bitwise Mismatch** check isn't available in Visual Studio 2019, even though you can configure it in the Options dialog.

::: moniker-end

## See also

[C++ Team Blog - IntelliSense Code Linter for C++](https://devblogs.microsoft.com/cppblog/intellisense-code-linter-for-cpp/)
78 changes: 78 additions & 0 deletions docs/ide/lnt-accidental-copy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
title: lnt-accidental-copy
description: "Reference for Visual Studio C++ IntelliSense Linter check lnt-accidental-copy."
ms.date: 09/29/2021
f1_keywords: ["lnt-accidental-copy"]
helpviewer_keywords: ["lnt-accidental-copy"]
monikerRange: ">=msvc-160"
---
# `lnt-accidental-copy`

A copy is being made because `auto` doesn't deduce references.

Variables declared by using `auto` are never deduced to be type references. If you initialize an `auto` variable from the result of a function that returns by reference, it results in a copy. Sometimes this effect is desirable, but in many cases it causes an unintentional copy.

The `lnt-accidental-copy` check is controlled by the **Accidental Copy** setting in the C/C++ Code Style options. For information on how to change this setting, see [Configure the linter](cpp-linter-overview.md#configure-the-linter).

## Examples

```cpp
#include <string>
#include <vector>

std::string& return_by_ref();

int& return_int_by_ref();

void accidental_copy(std::vector<std::string>& strings)
{
for (auto s : strings) {} // Flagged: A new copy of each string is
// made when the vector is iterated.

auto s = return_by_ref(); // Flagged: the function returns by-reference
// but a copy is made to initialize 's'.

auto i = return_int_by_ref(); // Not flagged because no copy constructor is called.
}
```

## How to fix the issue

The fix the linter suggests is to change `auto` to `auto&` on the declaration.

```cpp
#include <string>

std::string& return_by_ref();

void accidental_copy(std::vector<std::string>& strings)
{
for (auto& s : strings) {}

auto& s = return_by_ref();
}
```

## Remarks

The suggested fix isn't safe to apply in all cases. The fix may cause a compilation error or change the behavior of the code. It's important to understand how the suggested fix affects the code before applying it.

In cases where a temporary is returned, `const auto&` is necessary to prevent a compilation error. In this case, it may be preferable to continue to use `auto`.

Sometimes a copy is intentional, such as when you want to modify the copy without affecting the source instance, as shown in this example.

```cpp
void modifies_string(std::string& s);

void example(std::vector<std::string>& strings)
{
for (auto s : strings) {
modifies_string(s); // In this case, the copy may be intended so that
// the original strings are not modified.
}
}
```

## See also

[IntelliSense code linter for C++ overview](cpp-linter-overview.md)
42 changes: 42 additions & 0 deletions docs/ide/lnt-arithmetic-overflow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
title: lnt-arithmetic-overflow
description: "Reference for Visual Studio C++ IntelliSense Linter check lnt-arithmetic-overflow."
ms.date: 09/29/2021
f1_keywords: ["lnt-arithmetic-overflow"]
helpviewer_keywords: ["lnt-arithmetic-overflow"]
monikerRange: ">=msvc-160"
---
# `lnt-arithmetic-overflow`

An arithmetic expression may overflow before being converted to a wider type.

In C and C++, arithmetic operations are evaluated using the widest type of the operands, not the width of the type assigned the result. When a result is converted to a wider type, it indicates the developer expects the operation may overflow the narrower types of the operands.

The `lnt-arithmetic-overflow` check is controlled by the **Arithmetic Overflow** setting in the C/C++ Code Style options. For information on how to change this setting, see [Configure the linter](cpp-linter-overview.md#configure-the-linter).

## Examples

```cpp
void overflow(int a, int b) {
int64_t mul = a * b; // Flagged: 32-bit operation may overflow.
int64_t shift = a << 34; // Flagged: Shift would overflow.

int64_t mul2 = mul + b; // OK: 'mul' is 64-bit so the addition expression is
// evaluated using 64-bit operations.
}
```

## How to fix this issue

The fix the linter suggests is to explicitly widen one of the operands. Then the entire expression is evaluated at the wider result type, as shown in this example:

```cpp
void overflow(int a, int b) {
int64_t mul = static_cast<int64_t>(a) * b;
int64_t shift = static_cast<int64_t>(a) << 34;
}
```

## See also

[IntelliSense code linter for C++ overview](cpp-linter-overview.md)
68 changes: 68 additions & 0 deletions docs/ide/lnt-assignment-equality.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
---
title: lnt-assignment-equality
description: "Reference for Visual Studio C++ IntelliSense Linter check lnt-assignment-equality."
ms.date: 09/29/2021
f1_keywords: ["lnt-assignment-equality"]
helpviewer_keywords: ["lnt-assignment-equality"]
monikerRange: ">=msvc-160"
---
# `lnt-assignment-equality`

A variable is assigned a constant in a Boolean context.

An assignment expression that takes a constant always evaluates to the value of the constant. A comparison operation, such as `==` or `!=`, was probably intended instead.

::: moniker range=">=msvc-170"

In Visual Studio 2022, The `lnt-assignment-equality` check is controlled by the **Accidental Assignment** setting in the C/C++ Code Style options. For information on how to change this setting, see [Configure the linter](cpp-linter-overview.md#configure-the-linter).

::: moniker-end
::: moniker range="msvc-160"

In Visual Studio 2019, the `lnt-assignment-equality` check is controlled by the **Assignation Instead of Equality** setting in the C/C++ Code Style options. For information on how to change this setting, see [Configure the linter](cpp-linter-overview.md#configure-the-linter).

::: moniker-end

## Examples

```cpp
int read();

void accidental_assignment(int i)
{
if (i = 2) {} // Flagged: 'i' is being assigned to a constant.

if (i = read()) {} // OK: 'i' is being assigned the result of a function call.

while (i = 0) {} // Flagged.
}
```

## How to fix the issue

The fix the linter suggests is to change the assignment operator to an equality operator.

```cpp
void accidental_assignment(int i)
{
if (i == 2) {}

while (i != 0) {}
}
```

## Remarks

This check only flags assignment from a constant or constant expression.

## Known Issues

```cpp
void known_issues(bool b) {
if (b = true) {} // Not flagged because there is no implicit conversion to bool.
}
```

## See also

[IntelliSense code linter for C++ overview](cpp-linter-overview.md)
64 changes: 64 additions & 0 deletions docs/ide/lnt-integer-float-division.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
title: lnt-integer-float-division
description: "Reference for Visual Studio C++ IntelliSense Linter check lnt-integer-float-division."
ms.date: 09/29/2021
f1_keywords: ["lnt-integer-float-division"]
helpviewer_keywords: ["lnt-integer-float-division"]
monikerRange: ">=msvc-160"
---
# `lnt-integer-float-division`

An integer division expression was implicitly cast to a floating-point type.

The division is carried out using integer operations, which truncates the fractional part before it's assigned to the floating-point result type. This check doesn't always indicate a bug, because sometimes the truncation is intentional.

::: moniker range=">=msvc-170"

In Visual Studio 2022, the `lnt-integer-float-division` check is controlled by the **Truncated Division Result** setting in the C/C++ Code Style options. For information on how to change this setting, see [Configure the linter](cpp-linter-overview.md#configure-the-linter).

::: moniker-end
::: moniker range="msvc-160"

In Visual Studio 2019, the `lnt-integer-float-division` check is controlled by the **Integer division converted to floating point** setting in the C/C++ Code Style options. For information on how to change this setting, see [Configure the linter](cpp-linter-overview.md#configure-the-linter).

::: moniker-end

## Examples

```cpp
float divide(int i, int j) {
return i / j; // Flagged: The integer division result is implicitly cast to float.
}

float half(int i) {
return i / 2; // Flagged: An integer literal is used.
}
```

## How to fix the issue

The fix the linter suggests is to explicitly cast one of the division operands to a floating-point type, so the division result isn't truncated. You can also use a floating-point literal instead of a cast.

```cpp
float divide(int i, int j) {
return static_cast<float>(i) / j;
}

float half(int i) {
return i / 2.0;
}
```

## Remarks

If the truncation is intentional, you can add an explicit cast to prevent the warning.

```cpp
float int_divide(int i, int j) {
return static_cast<float>(i / j); // Not flagged because of the explicit cast.
}
```

## See also

[IntelliSense code linter for C++ overview](cpp-linter-overview.md)
49 changes: 49 additions & 0 deletions docs/ide/lnt-logical-bitwise-mismatch.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
---
title: lnt-logical-bitwise-mismatch
description: "Reference for Visual Studio C++ IntelliSense Linter check lnt-logical-bitwise-mismatch."
ms.date: 09/29/2021
f1_keywords: ["lnt-logical-bitwise-mismatch"]
helpviewer_keywords: ["lnt-logical-bitwise-mismatch"]
monikerRange: ">=msvc-160"
---
# `lnt-logical-bitwise-mismatch`

A logical operator was used with integer values or a bitwise operator was used with Boolean values.

While the flagged code still compiles, it's considered bad practice to use operators incorrectly: it makes the code harder to read or modify, and may cause runtime errors.

The `lnt-logical-bitwise-mismatch` check is controlled by the **Logical/Bitwise Mismatch** setting in the C/C++ Code Style options. For information on how to change this setting, see [Configure the linter](cpp-linter-overview.md#configure-the-linter).

## Examples

Only use logical operators on Boolean values.

```cpp
void example(bool a, bool b) {
bool c = a & b; // Flagged: Bitwise AND operator used with Boolean variables.
bool d = a || b; // OK: Logical OR operator used with Boolean variables.
}

```

Only use bitwise operators on integer values.

```cpp
void example(int i, int j) {
int k = i && j; // Flagged: Logical AND operator used with integer variables.
// The runtime behavior will be incorrect in almost all cases.
bool l = i ^ j; // OK: Bitwise XOR operator used with integer variables.
}
```

## How to fix the issue

The fix the linter suggests is to use the correct operator for the operand type.

## Known issues

Alternative tokens such as `and` or `bitor` are flagged by the check, but the suggested fix is incorrect.

## See also

[IntelliSense code linter for C++ overview](cpp-linter-overview.md)
Loading