Skip to content

Repo sync for protected CLA branch #4493

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 9 commits into from
Apr 4, 2023
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
16 changes: 8 additions & 8 deletions docs/atl/reference/compiler-options-macros.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ ms.date: 02/01/2023
f1_keywords: ["_ATL_ALL_WARNINGS", "_ATL_APARTMENT_THREADED", "_ATL_CSTRING_EXPLICIT_CONSTRUCTORS ", "_ATL_ENABLE_PTM_WARNING", "_ATL_FREE_THREADED", "_ATL_MODULES", "_ATL_MULTI_THREADED", "_ATL_NO_AUTOMATIC_NAMESPACE", "_ATL_NO_COM_SUPPORT", "ATL_NO_VTABLE", "ATL_NOINLINE", "_ATL_SINGLE_THREADED"]
helpviewer_keywords: ["compiler options, macros"]
---
# Compiler Options Macros
# Compiler Options Macros acrolinx

These macros control specific compiler features.

Expand All @@ -14,7 +14,7 @@ These macros control specific compiler features.
|[`_ATL_ALL_WARNINGS`](#_atl_all_warnings)|A symbol that enables errors in projects converted from previous versions of ATL.|
|[`_ATL_APARTMENT_THREADED`](#_atl_apartment_threaded)|Define if one or more of your objects use apartment threading.|
|[`_ATL_CSTRING_EXPLICIT_CONSTRUCTORS`](#_atl_cstring_explicit_constructors)|Makes certain `CString` constructors explicit, preventing any unintentional conversions.|
|[`_ATL_ENABLE_PTM_WARNING`](#_atl_enable_ptm_warning)|Define this macro to require C++ standard syntax. It generates the C4867 compiler error when non-standard syntax is used to initialize a pointer to a member function.|
|[`_ATL_ENABLE_PTM_WARNING`](#_atl_enable_ptm_warning)|Define this macro to require C++ standard syntax. It generates the C4867 compiler error when nonstandard syntax is used to initialize a pointer to a member function.|
|[`_ATL_FREE_THREADED`](#_atl_free_threaded)|Define if one or more of your objects use free or neutral threading.|
|[`_ATL_MODULES`](#_ATL_MODULES)|Allows you to compile ATL projects with [permissive-](../../build/reference/permissive-standards-conformance.md) and use ATL with [C++ modules](../../cpp/modules-cpp.md).|
|[`_ATL_MULTI_THREADED`](#_atl_multi_threaded)|A symbol that indicates the project has objects marked as Both, Free or Neutral. The macro [`_ATL_FREE_THREADED`](#_atl_free_threaded) should be used instead.|
Expand Down Expand Up @@ -64,7 +64,7 @@ New projects have this `#define` set in *pch.h* (*stdafx.h* in Visual Studio 201

Define if one or more of your objects use apartment threading.

```
```cpp
_ATL_APARTMENT_THREADED
```

Expand All @@ -88,7 +88,7 @@ By using the `_T` macro on all constructor string arguments, you can define `_AT

## <a name="_atl_enable_ptm_warning"></a> `_ATL_ENABLE_PTM_WARNING`

Define this macro in order to force the use of ANSI C++ standard-conforming syntax for pointer to member functions. Using this macro causes the C4867 compiler error to be generated when non-standard syntax is used to initialize a pointer to a member function.
Define this macro in order to force the use of ANSI C++ standard-conforming syntax for pointer to member functions. Using this macro causes the C4867 compiler error to be generated when nonstandard syntax is used to initialize a pointer to a member function.

```cpp
#define _ATL_ENABLE_PTM_WARNING
Expand All @@ -100,7 +100,7 @@ The ATL and MFC libraries have been changed to match the Microsoft C++ compiler'

When [`_ATL_ENABLE_PTM_WARNING`](#_atl_enable_ptm_warning) isn't defined (the default case), ATL/MFC disables the C4867 error in macro maps (notably message maps) so that code that was created in earlier versions can continue to build as before. If you define `_ATL_ENABLE_PTM_WARNING`, your code should conform to the C++ standard.

However, the non-standard form has been deprecated. You need to move existing code to C++ standard syntax. For example, the following code:
However, the nonstandard form has been deprecated. You need to move existing code to C++ standard syntax. For example, the following code:

[!code-cpp[NVC_MFCListView#14](../../atl/reference/codesnippet/cpp/compiler-options-macros_2.cpp)]

Expand Down Expand Up @@ -132,7 +132,7 @@ _ATL_MODULES

## <a name="_atl_multi_threaded"></a> `_ATL_MULTI_THREADED`

A symbol that indicates the project will have objects that are marked as Both, Free or Neutral.
A symbol that indicates the project has objects that are marked as Both, Free or Neutral.

```
_ATL_MULTI_THREADED
Expand Down Expand Up @@ -193,11 +193,11 @@ A symbol that indicates a function shouldn't be inlined.
### Parameters

*`myfunction`*\
The function that should not be inlined.
The function that shouldn't be inlined.

### Remarks

Use this symbol if you want to ensure a function does not get inlined by the compiler, even though it must be declared as inline so that it can be placed in a header file. Expands to `__declspec(noinline)`.
Use this symbol if you want to ensure a function doesn't get inlined by the compiler, even though it must be declared as inline so that it can be placed in a header file. Expands to `__declspec(noinline)`.

## <a name="_atl_single_threaded"></a> `_ATL_SINGLE_THREADED`

Expand Down
25 changes: 13 additions & 12 deletions docs/cpp/cpp-bit-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ description: "Learn more about: C++ Bit Fields"
title: "C++ Bit Fields"
ms.date: "11/19/2018"
helpviewer_keywords: ["bitfields [C++]", "fields [C++], bit", "bit fields"]
ms.assetid: 6f4b62e3-cc1d-4e5d-bf34-05904104f71a
---
# C++ Bit Fields

Expand All @@ -15,7 +14,7 @@ Classes and structures can contain members that occupy less storage than an inte

## Remarks

The (optional) *declarator* is the name by which the member is accessed in the program. It must be an integral type (including enumerated types). The *constant-expression* specifies the number of bits the member occupies in the structure. Anonymous bit fieldsthat is, bit-field members with no identifiercan be used for padding.
The (optional) *declarator* is the name by which the member is accessed in the program. It must be an integral type (including enumerated types). The *constant-expression* specifies the number of bits the member occupies in the structure. Anonymous bit fieldsthat is, bit-field members with no identifiercan be used for padding.

> [!NOTE]
> An unnamed bit field of width 0 forces alignment of the next bit field to the next **type** boundary, where **type** is the type of the member.
Expand All @@ -33,20 +32,21 @@ struct Date {
};
```

The conceptual memory layout of an object of type `Date` is shown in the following figure.
The conceptual memory layout of an object of type `Date` is shown in the following figure:

![Memory layout of a date object, showing the nWeekDay, nMonthDay, nMonth, and nYear bit fields.](../cpp/media/vc38uq1.png "Memory layout of a date object") <br/>
Memory Layout of Date Object
:::image type="complex" source="../cpp/media/vc38uq1.png" alt-text="Diagram of the memory layout of a date object, showing where the n WeekDay, n MonthDay, n Month, and n Year bit fields are located.":::
32 bits of memory are displayed in a row. Starting with the least significant bit, 3 bits are for nWeekDay. The next 6 bits are for nMonthDay. The next 5 bits are for nMonth. The next 2 bits are unused. The next 8 bits are for nYear. The remaining 8 bits are unused.
:::image-end:::

Note that `nYear` is 8 bits long and would overflow the word boundary of the declared type, **`unsigned short`**. Therefore, it is begun at the beginning of a new **`unsigned short`**. It is not necessary that all bit fields fit in one object of the underlying type; new units of storage are allocated, according to the number of bits requested in the declaration.
`nYear` is 8 bits long, which would overflow the word boundary of the declared type, **`unsigned short`**. Therefore, it starts at the beginning of a new **`unsigned short`**. It isn't necessary that all bit fields fit in one object of the underlying type; new units of storage are allocated, according to the number of bits requested in the declaration.

**Microsoft Specific**

The ordering of data declared as bit fields is from low to high bit, as shown in the figure above.
The ordering of data declared as bit fields is from low to high bit, as shown in the previous figure.

**END Microsoft Specific**

If the declaration of a structure includes an unnamed field of length 0, as shown in the following example,
If the declaration of a structure includes an unnamed field of length 0, as shown in the following example:

```cpp
// bit_fields2.cpp
Expand All @@ -60,14 +60,15 @@ struct Date {
};
```

then the memory layout is as shown in the following figure:
Then the memory layout is as shown in the following figure:

![Layout of a Date object with a zero length bit field, which forces alignment padding.](../cpp/media/vc38uq2.png) <br/>
Layout of Date Object with Zero-Length Bit Field
:::image type="complex" source="../cpp/media/vc38uq2.png" alt-text="Diagram of the layout of a Date object, with a zero length bit field, which forces alignment padding.":::
64 bits of memory are displayed in a row. Starting with the least significant bit, 5 bits are for n Month. The next 8 bits are for n Year. The next 19 bits are unused. The next 3 bits are for n WeekDay. The next 6 bits are for n MonthDay. The remaining bits are unused.
:::image-end:::

The underlying type of a bit field must be an integral type, as described in [Built-in types](../cpp/fundamental-types-cpp.md).

If the initializer for a reference of type `const T&` is an lvalue that refers to a bit field of type `T`, the reference is not bound to the bit field directly. Instead, the reference is bound to a temporary initialized to hold the value of the bit field.
If the initializer for a reference of type `const T&` is an lvalue that refers to a bit field of type `T`, the reference isn't bound to the bit field directly. Instead, the reference is bound to a temporary initialized to hold the value of the bit field.

## Restrictions on bit fields

Expand Down
38 changes: 21 additions & 17 deletions docs/cpp/dynamic-cast-operator.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ description: "Overview of the C++ language dynamic_cast operator."
ms.date: "02/03/2020"
f1_keywords: ["dynamic_cast_cpp"]
helpviewer_keywords: ["dynamic_cast keyword [C++]"]
ms.assetid: f380ada8-6a18-4547-93c9-63407f19856b
---
# dynamic_cast Operator

Expand All @@ -20,15 +19,15 @@ dynamic_cast < type-id > ( expression )

The `type-id` must be a pointer or a reference to a previously defined class type or a "pointer to void". The type of `expression` must be a pointer if `type-id` is a pointer, or an l-value if `type-id` is a reference.

See [static_cast](../cpp/static-cast-operator.md) for an explanation of the difference between static and dynamic casting conversions, and when it is appropriate to use each.
See [static_cast](../cpp/static-cast-operator.md) for an explanation of the difference between static and dynamic casting conversions, and when it's appropriate to use each.

There are two breaking changes in the behavior of **`dynamic_cast`** in managed code:

- **`dynamic_cast`** to a pointer to the underlying type of a boxed enum will fail at runtime, returning 0 instead of the converted pointer.

- **`dynamic_cast`** will no longer throw an exception when `type-id` is an interior pointer to a value type, with the cast failing at runtime. The cast will now return the 0 pointer value instead of throwing.
- **`dynamic_cast`** will no longer throw an exception when `type-id` is an interior pointer to a value type; instead, the cast fails at runtime. The cast returns the 0 pointer value instead of throwing.

If `type-id` is a pointer to an unambiguous accessible direct or indirect base class of `expression`, a pointer to the unique subobject of type `type-id` is the result. For example:
If `type-id` is a pointer to an unambiguous accessible direct or indirect base class of `expression`, then a pointer to the unique subobject of type `type-id` is the result. For example:

```cpp
// dynamic_cast_1.cpp
Expand All @@ -45,7 +44,7 @@ void f(D* pd) {
}
```

This type of conversion is called an "upcast" because it moves a pointer up a class hierarchy, from a derived class to a class it is derived from. An upcast is an implicit conversion.
This type of conversion is called an "upcast" because it moves a pointer up a class hierarchy, from a derived class to a class it's derived from. An upcast is an implicit conversion.

If `type-id` is void*, a run-time check is made to determine the actual type of `expression`. The result is a pointer to the complete object pointed to by `expression`. For example:

Expand All @@ -66,7 +65,7 @@ void f() {
}
```

If `type-id` is not void*, a run-time check is made to see if the object pointed to by `expression` can be converted to the type pointed to by `type-id`.
If `type-id` isn't `void*`, a run-time check is made to see if the object pointed to by `expression` can be converted to the type pointed to by `type-id`.

If the type of `expression` is a base class of the type of `type-id`, a run-time check is made to see if `expression` actually points to a complete object of the type of `type-id`. If this is true, the result is a pointer to a complete object of the type of `type-id`. For example:

Expand Down Expand Up @@ -114,8 +113,9 @@ int main() {
}
```

![Class hierarchy that shows multiple inheritance.](../cpp/media/vc39011.gif "Class hierarchy that shows multiple inheritance") <br/>
Class hierarchy that shows multiple inheritance
:::image type="complex" source="../cpp/media/vc39011.gif" alt-text="Diagram that shows multiple inheritance.":::
The diagram shows a class hierarchy with A as a base class of B which is a base class of D. A is also a base class for C, which is a base class for D. Class D inherits from both B and C.
:::image-end:::

A pointer to an object of type `D` can be safely cast to `B` or `C`. However, if `D` is cast to point to an `A` object, which instance of `A` would result? This would result in an ambiguous casting error. To get around this problem, you can perform two unambiguous casts. For example:

Expand All @@ -137,14 +137,18 @@ void f() {

Further ambiguities can be introduced when you use virtual base classes. Consider the class hierarchy shown in the following figure.

![Class hierarchy that shows virtual base classes.](../cpp/media/vc39012.gif "Class hierarchy that shows virtual base classes") <br/>
:::image type="complex" source="../cpp/media/vc39012.gif" alt-text="Diagram of a class hierarchy that shows virtual base classes.":::
The diagram shows the classes A, B, C, D, and E arranged as follows: Class A is a base class of B. Classes C and E each derive from B. Class E also inherits from D, which inherits from class B, which inherits from class A.
:::image-end:::
Class hierarchy that shows virtual base classes

In this hierarchy, `A` is a virtual base class. Given an instance of class `E` and a pointer to the `A` subobject, a **`dynamic_cast`** to a pointer to `B` will fail due to ambiguity. You must first cast back to the complete `E` object, then work your way back up the hierarchy, in an unambiguous manner, to reach the correct `B` object.
In this hierarchy, `A` is a virtual base class. Given an instance of class `E` and a pointer to the `A` subobject, a **`dynamic_cast`** to a pointer to `B` fails due to ambiguity. You must first cast back to the complete `E` object, then work your way back up the hierarchy, in an unambiguous manner, to reach the correct `B` object.

Consider the class hierarchy shown in the following figure.

![Class hierarchy that shows duplicate base classes.](../cpp/media/vc39013.gif "Class hierarchy that shows duplicate base classes") <br/>
:::image type="complex" source="../cpp/media/vc39013.gif" alt-text="Diagram of a class hierarchy that shows duplicate base classes.":::
The diagram shows the classes A, B, C, D, and E arranged as follows: Class B derives from Class A. Class C derives from class A. class D derives from class B. Class E derives from class C, which derives from class A. In this case, the duplicate base class is class A, which is directly or indirectly inherited by all the other classes. Class A is inherited directly by classes B and C, and indirectly by class D via class B, and indirectly by class E via class C, and indirectly in class D via class B.
:::image-end:::
Class hierarchy that shows duplicate base classes

Given an object of type `E` and a pointer to the `D` subobject, to navigate from the `D` subobject to the left-most `A` subobject, three conversions can be made. You can perform a **`dynamic_cast`** conversion from the `D` pointer to an `E` pointer, then a conversion (either **`dynamic_cast`** or an implicit conversion) from `E` to `B`, and finally an implicit conversion from `B` to `A`. For example:
Expand All @@ -165,9 +169,9 @@ void f(D* pd) {
}
```

The **`dynamic_cast`** operator can also be used to perform a "cross cast." Using the same class hierarchy, it is possible to cast a pointer, for example, from the `B` subobject to the `D` subobject, as long as the complete object is of type `E`.
The **`dynamic_cast`** operator can also be used to perform a "cross cast." Using the same class hierarchy, it's possible to cast a pointer, for example, from the `B` subobject to the `D` subobject, as long as the complete object is of type `E`.

Considering cross casts, it is actually possible to do the conversion from a pointer to `D` to a pointer to the left-most `A` subobject in just two steps. You can perform a cross cast from `D` to `B`, then an implicit conversion from `B` to `A`. For example:
Considering cross casts, it's possible to do the conversion from a pointer to `D` to a pointer to the left-most `A` subobject in just two steps. You can perform a cross cast from `D` to `B`, then an implicit conversion from `B` to `A`. For example:

```cpp
// dynamic_cast_6.cpp
Expand All @@ -186,7 +190,7 @@ void f(D* pd) {

A null pointer value is converted to the null pointer value of the destination type by **`dynamic_cast`**.

When you use `dynamic_cast < type-id > ( expression )`, if `expression` cannot be safely converted to type `type-id`, the run-time check causes the cast to fail. For example:
When you use `dynamic_cast < type-id > ( expression )`, if `expression` can't be safely converted to type `type-id`, the run-time check causes the cast to fail. For example:

```cpp
// dynamic_cast_7.cpp
Expand All @@ -201,15 +205,15 @@ void f() {
}
```

The value of a failed cast to pointer type is the null pointer. A failed cast to reference type throws a [bad_cast Exception](../cpp/bad-cast-exception.md). If `expression` does not point to or reference a valid object, a `__non_rtti_object` exception is thrown.
The value of a failed cast to pointer type is the null pointer. A failed cast to reference type throws a [bad_cast Exception](../cpp/bad-cast-exception.md). If `expression` doesn't point to or reference a valid object, a `__non_rtti_object` exception is thrown.

See [typeid](../cpp/typeid-operator.md) for an explanation of the `__non_rtti_object` exception.

## Example

The following sample creates the base class (struct A) pointer, to an object (struct C). This, plus the fact there are virtual functions, enables runtime polymorphism.

The sample also calls a non-virtual function in the hierarchy.
The sample also calls a nonvirtual function in the hierarchy.

```cpp
// dynamic_cast_8.cpp
Expand Down Expand Up @@ -270,7 +274,7 @@ int main() {
C ConStack;
Globaltest(ConStack);

// will fail because B knows nothing about C
// fails because B knows nothing about C
B BonStack;
Globaltest(BonStack);
}
Expand Down
Loading