Skip to content

Repo sync for protected CLA branch #3012

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 11 commits into from
Mar 3, 2021
6 changes: 3 additions & 3 deletions docs/build/cmake-remote-debugging.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ In this tutorial, you'll learn how to:

To set up Visual Studio for cross-platform C++ development, install the build tools for the target architecture. For this tutorial, install the ARM64 build tools by doing the following:

1. Run the Visual Studio Installer. If you haven't installed Visual Studio yet, see [Install Visual Studio](https://docs.microsoft.com/visualstudio/install/install-visual-studio#:~:text=Install%20Visual%20Studio%201%20Make%20sure%20your%20computer,...%204%20Choose%20workloads.%20...%20More%20items...%20)
1. Run the Visual Studio Installer. If you haven't installed Visual Studio yet, see [Install Visual Studio](/visualstudio/install/install-visual-studio)
1. On the Visual Studio Installer home screen, choose **Modify**.
1. From the choices at the top, choose **Individual components**.
1. Scroll down to the **Compilers, build tools, and runtimes** section.
Expand All @@ -37,8 +37,8 @@ To set up Visual Studio for cross-platform C++ development, install the build to

### On the remote machine

1. Install the remote tools on the remote machine. For this tutorial, install the ARM64 tools by following the instructions in [Download and Install the remote tools](https://docs.microsoft.com/visualstudio/debugger/remote-debugging-cpp?%23download-and-install-the-remote-tools#download-and-install-the-remote-tools).
1. Start and configure the remote debugger on the remote machine. For this tutorial, do so by following the directions in [set up the remote debugger](https://docs.microsoft.com/visualstudio/debugger/remote-debugging-cpp?%23download-and-install-the-remote-tools#BKMK_setup) on the remote Windows machine.
1. Install the remote tools on the remote machine. For this tutorial, install the ARM64 tools by following the instructions in [Download and Install the remote tools](/visualstudio/debugger/remote-debugging-cpp#download-and-install-the-remote-tools).
1. Start and configure the remote debugger on the remote machine. For this tutorial, do so by following the directions in [set up the remote debugger](/visualstudio/debugger/remote-debugging-cpp#BKMK_setup) on the remote Windows machine.

## Create a CMake project

Expand Down
53 changes: 28 additions & 25 deletions docs/cpp/abstract-classes-cpp.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,16 @@
---
description: "Learn more about: Abstract Classes (C++)"
title: "Abstract Classes (C++)"
ms.date: "11/04/2016"
description: "Learn more about: Abstract classes (C++)"
title: "Abstract classes (C++)"
ms.date: 02/18/2021
helpviewer_keywords: ["classes [C++], abstract", "base classes [C++], abstract classes [C++]", "abstract classes [C++]", "derived classes [C++], abstract classes [C++]"]
ms.assetid: f0c5975b-39de-4d68-9640-6ce57f4632e6
---
# Abstract Classes (C++)
# Abstract classes (C++)

Abstract classes act as expressions of general concepts from which more specific classes can be derived. You cannot create an object of an abstract class type; however, you can use pointers and references to abstract class types.
Abstract classes act as expressions of general concepts from which more specific classes can be derived. You can't create an object of an abstract class type. However, you can use pointers and references to abstract class types.

A class that contains at least one pure virtual function is considered an abstract class. Classes derived from the abstract class must implement the pure virtual function or they, too, are abstract classes.
You create an abstract class by declaring at least one pure virtual member function. That's a virtual function declared by using the pure specifier (`= 0`) syntax. Classes derived from the abstract class must implement the pure virtual function or they, too, are abstract classes.

Consider the example presented in [Virtual Functions](../cpp/virtual-functions.md). The intent of class `Account` is to provide general functionality, but objects of type `Account` are too general to be useful. Therefore, `Account` is a good candidate for an abstract class:
Consider the example presented in [Virtual functions](../cpp/virtual-functions.md). The intent of class `Account` is to provide general functionality, but objects of type `Account` are too general to be useful. That means `Account` is a good candidate for an abstract class:

```cpp
// deriv_AbstractClasses.cpp
Expand All @@ -30,7 +29,7 @@ The only difference between this declaration and the previous one is that `Print

## Restrictions on abstract classes

Abstract classes cannot be used for:
Abstract classes can't be used for:

- Variables or member data

Expand All @@ -40,42 +39,46 @@ Abstract classes cannot be used for:

- Types of explicit conversions

Another restriction is that if the constructor for an abstract class calls a pure virtual function, either directly or indirectly, the result is undefined. However, constructors and destructors for abstract classes can call other member functions.
If the constructor for an abstract class calls a pure virtual function, either directly or indirectly, the result is undefined. However, constructors and destructors for abstract classes can call other member functions.

Pure virtual functions can be defined for abstract classes, but they can be called directly only by using the syntax:
## Defined pure virtual functions

Pure virtual functions in abstract classes can be *defined*, or have an implementation. You can only call such functions by using the fully qualified syntax:

*abstract-class-name*::*function-name*()

This helps when designing class hierarchies whose base class(es) include pure virtual destructors, because base class destructors are always called in the process of destroying an object. Consider the following example:
Defined pure virtual functions are helpful when you design class hierarchies whose base classes include pure virtual destructors. That's because base class destructors are always called during object destruction. Consider the following example:

```cpp
// deriv_RestrictionsOnUsingAbstractClasses.cpp
// Declare an abstract base class with a pure virtual destructor.
// deriv_RestrictionsonUsingAbstractClasses.cpp
class base {
// It's the simplest possible abstract class.
class base
{
public:
base() {}
virtual ~base()=0;
virtual ~base() = 0 {}; // pure virtual, and defined!
};

// Provide a definition for destructor.
base::~base() {}

class derived:public base {
class derived : public base
{
public:
derived() {}
~derived(){}
~derived() {}
};

int main() {
derived *pDerived = new derived;
delete pDerived;
int main()
{
derived aDerived; // destructor called when it goes out of scope
}
```

When the object pointed to by `pDerived` is deleted, the destructor for class `derived` is called and then the destructor for class `base` is called. The empty implementation for the pure virtual function ensures that at least some implementation exists for the function.
The example shows the definition of `~base()` inline, but you can also define it outside the class by using `base::~base() {}`.

When the object `aDerived` goes out of scope, the destructor for class `derived` is called. The compiler generates code to implicitly call the destructor for class `base` after the `derived` destructor. The empty implementation for the pure virtual function `~base` ensures that at least some implementation exists for the function. Without it, the linker generates an unresolved external symbol error for the implicit call.

> [!NOTE]
> In the preceding example, the pure virtual function `base::~base` is called implicitly from `derived::~derived`. It is also possible to call pure virtual functions explicitly using a fully qualified member-function name.
> In the preceding example, the pure virtual function `base::~base` is called implicitly from `derived::~derived`. It's also possible to call pure virtual functions explicitly by using a fully qualified member-function name. Such functions must have an implementation, or the call results in an error at link time.

## See also

Expand Down
19 changes: 13 additions & 6 deletions docs/error-messages/compiler-errors-1/fatal-error-c1047.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
---
description: "Learn more about: Fatal Error C1047"
title: "Fatal Error C1047"
ms.date: "11/04/2016"
ms.date: 02/17/2021
f1_keywords: ["C1047"]
helpviewer_keywords: ["C1047"]
ms.assetid: e1bbbc6b-a5bc-4c23-8203-488120a0ec78
---
# Fatal Error C1047

The object or library file 'file' was created with an older compiler than other objects; rebuild old objects and libraries
> The object or library file '*filename*' was created with an older compiler than other objects; rebuild old objects and libraries

C1047 is caused when object files or libraries built with **/LTCG** are linked together, but where those object files or libraries are built with different versions of the Visual C++ toolset.
This error can happen if you use a new version of the compiler to build your project, but don't do a clean rebuild of existing object files or libraries.

This can happen if you begin using a new version of the compiler but do not do a clean rebuild of existing object files or libraries.
## Remarks

To resolve C1047, rebuild all object files or libraries.
C1047 is caused when object files or libraries built by using **`/GL`** or **`/LTCG`** in different versions of the Visual Studio C/C++ compiler toolset get linked together. For example, you can't link a **`/LTCG`** library built by using Visual Studio 2019 version 16.7 to an app built by using Visual Studio 2019 version 16.8. Both the major and minor update numbers of the toolset used to compile the objects and libraries must match exactly.

To resolve C1047, rebuild all object files or libraries by using the same version of the toolset.

## See also

[`/GL` (Whole Program Optimization)](../../build/reference/gl-whole-program-optimization.md)\
[`/LTCG` (Link-time code generation)](../../build/reference/ltcg-link-time-code-generation.md)\
[C++ binary compatibility 2015-2019](../../porting/binary-compat-2015-2017.md)
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ For information about reason codes, refer to the next part of this article.
| Informational message | Description |
|--|--|
| 5001 | Loop vectorized. |
| 5002 | Loop not vectorized due to reason '*description*'. |
| 5002 | Loop not vectorized because of reason '*description*'. |
| 5011 | Loop parallelized. |
| 5012 | Loop not parallelized due to reason '*description*'. |
| 5012 | Loop not parallelized because of reason '*description*'. |
| 5021 | Unable to associate loop with pragma. |

The following sections list possible reason codes for the parallelizer and vectorizer.
Expand All @@ -30,11 +30,12 @@ The 5*xx* reason codes apply to both the parallelizer and the vectorizer.

| Reason code | Explanation |
|--|--|
| 500 | A generic message that covers several cases—for example, the loop includes multiple exits, or the loop header doesn't end by incrementing the induction variable. |
| 500 | A generic message that covers several cases: For example, the loop includes multiple exits, or the loop header doesn't end by incrementing the induction variable. |
| 501 | Induction variable isn't local; or upper bound isn't loop-invariant. |
| 502 | Induction variable is stepped in some manner other than a simple +1. |
| 503 | Loop includes exception-handling or switch statements. |
| 504 | Loop body may throw an exception that requires destruction of a C++ object. |
| 505 | Outer loop has a pre-incremented induction variable. Exiting analysis. |

```cpp
void code_500(int *A)
Expand Down Expand Up @@ -72,7 +73,7 @@ void code_501_example1(int *A)
{
// Code 501 is emitted if the compiler cannot discern the
// induction variable of this loop. In this case, when it checks
// the upperbound of 'i', the compiler cannot prove that the
// the upper bound of 'i', the compiler cannot prove that the
// function call "bound()" returns the same value each time.
// Also, the compiler cannot prove that the call to "bound()"
// does not modify the values of array A.
Expand All @@ -83,7 +84,7 @@ void code_501_example1(int *A)
}

// To resolve code 501, ensure that the induction variable is
// a local variable, and ensure that the upperbound is a
// a local variable, and ensure that the upper bound is a
// provably loop invariant value.

for (int i=0, imax = bound(); i<imax; ++i)
Expand All @@ -105,7 +106,7 @@ void code_501_example2(int *A)
}

// To resolve code 501, ensure that the induction variable is
// a local variable, and ensure that the upperbound is a
// a local variable, and ensure that the upper bound is a
// provably loop invariant value.

for (int i=0; i<1000; ++i)
Expand Down Expand Up @@ -173,7 +174,8 @@ public:
~C504();
};

void code_504(int *A) {
void code_504(int *A)
{
// Code 504 is emitted if a C++ object was created and
// that object requires EH unwind tracking information under
// /EHs or /EHsc.
Expand All @@ -185,6 +187,23 @@ void code_504(int *A) {
}

}

void code_505(int *A)
{
// Code 505 is emitted on outer loops with pre-incremented
// induction variables. The vectorizer/parallelizer analysis
// package doesn't support these loops, and they are
// intentionally not converted to post-increment loops to
// prevent a performance degradation.

// To parallelize an outer loop that causes code 505, change
// it to a post-incremented loop.

for (int i=100; i--; )
for (int j=0; j<100; j++) { // this loop is still vectorized
A[j] = A[j] + 1;
}
}
```

## <a name="BKMK_ReasonCode100x"></a> 10xx reason codes
Expand All @@ -201,7 +220,7 @@ The 10*xx* reason codes apply to the parallelizer.
| 1005 | The `no_parallel` pragma was specified. |
| 1006 | This function contains OpenMP. Resolve it by removing any OpenMP in this function. |
| 1007 | The loop induction variable or the loop bounds aren't signed 32-bit numbers (`int` or `long`). Resolve it by changing the type of the induction variable. |
| 1008 | The compiler detected that this loop doesn't perform enough work to justify auto-parallelization. |
| 1008 | The compiler detected that this loop doesn't do enough work to justify auto-parallelization. |
| 1009 | The compiler detected an attempt to parallelize a "`do`-`while`" loop. The auto-parallelizer only targets "`for`" loops. |
| 1010 | The compiler detected that the loop is using "not-equals" (`!=`) for its condition. |

Expand Down Expand Up @@ -403,7 +422,7 @@ The 11*xx* reason codes apply to the vectorizer.
| Reason code | Explanation |
|--|--|
| 1100 | Loop contains control flow—for example, "`if`" or "`?:`". |
| 1101 | Loop contains datatype conversion—perhaps implicit—that can't be vectorized. |
| 1101 | Loop contains a (possibly implicit) datatype conversion that can't be vectorized. |
| 1102 | Loop contains non-arithmetic or other non-vectorizable operations. |
| 1103 | Loop body includes shift operations whose size might vary within the loop. |
| 1104 | Loop body includes scalar variables. |
Expand All @@ -423,7 +442,7 @@ void code_1100(int *A, int x)

for (int i=0; i<1000; ++i)
{
// straightline code is more amenable to vectorization
// straight line code is more amenable to vectorization
if (x)
{
A[i] = A[i] + 1;
Expand Down Expand Up @@ -550,7 +569,7 @@ The 12*xx* reason codes apply to the vectorizer.

| Reason code | Explanation |
|--|--|
| 1200 | Loop contains loop-carried data dependencies that prevent vectorization. Different iterations of the loop interfere with each other such that vectorizing the loop would produce wrong answers, and the auto-vectorizer can't prove to itself that there are no such data dependences. |
| 1200 | Loop contains loop-carried data dependencies that prevent vectorization. Different iterations of the loop interfere with each other such that vectorizing the loop would produce wrong answers, and the auto-vectorizer can't prove to itself that there aren't such data dependencies. |
| 1201 | Array base changes during the loop. |
| 1202 | Field in a struct isn't 32 or 64 bits wide. |
| 1203 | Loop body includes non-contiguous accesses into an array. |
Expand Down Expand Up @@ -642,7 +661,7 @@ The 13*xx* reason codes apply to the vectorizer.

| Reason code | Explanation |
|--|--|
| 1300 | Loop body contains no—or very little—computation. |
| 1300 | Loop body contains little or no computation. |
| 1301 | Loop stride isn't +1. |
| 1302 | Loop is a "`do`-`while`". |
| 1303 | Too few loop iterations for vectorization to provide value. |
Expand Down Expand Up @@ -692,7 +711,7 @@ int code_1303(int *A, int *B)
// make vectorization profitable.

// If the loop computation fits perfectly in
// vector registers - for example, the upperbound is 4, or 8 in
// vector registers - for example, the upper bound is 4, or 8 in
// this case - then the loop _may_ be vectorized.

// This loop is not vectorized because there are 5 iterations
Expand Down
2 changes: 1 addition & 1 deletion docs/overview/whats-new-cpp-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ For the latest C++ conformance status, see [C++ conformance improvements in Visu

## Community contributors

The following people contributed to the C++, C, and Assembler docs during this period. Thank you! See [Microsoft Docs contributor guide overview](https://docs.microsoft.com/contribute/) if you'd like to learn how to contribute.
The following people contributed to the C++, C, and Assembler docs during this period. Thank you! See [Microsoft Docs contributor guide overview](/contribute/) if you'd like to learn how to contribute.

- [yecril71pl](https://github.com/yecril71pl) - Christopher Yeleighton (4)
- [definedrisk](https://github.com/definedrisk) - Ben (3)
Expand Down
Loading