You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/cpp/cpp-bit-fields.md
+6-6Lines changed: 6 additions & 6 deletions
Original file line number
Diff line number
Diff line change
@@ -14,7 +14,7 @@ Classes and structures can contain members that occupy less storage than an inte
14
14
15
15
## Remarks
16
16
17
-
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 fields — that is, bit-field members with no identifier — can be used for padding.
17
+
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 fields—that is, bit-field members with no identifier—can be used for padding.
18
18
19
19
> [!NOTE]
20
20
> 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.
@@ -35,14 +35,14 @@ struct Date {
35
35
The conceptual memory layout of an object of type `Date` is shown in the following figure.
36
36
37
37
:::image type="complex" source="../cpp/media/vc38uq1.png" alt-text="Memory layout of a date object, showing where the nWeekDay, nMonthDay, nMonth, and nYear bit fields fall.":::
38
-
32 bits of memory are displayed in a row. The rightmost 3 bits are for nWeekDay. The next 6 bits to the left are for nMonthDay. The next 5 bits to the left are for nMonth. The next two bits are unused. The next 8 bits are for nYear. The remaining 8 bits to the left are unused.
38
+
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.
39
39
:::image-end:::
40
40
41
-
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.
41
+
`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.
42
42
43
43
**Microsoft Specific**
44
44
45
-
The ordering of data declared as bit fields is from low to high bit, as shown in the figure above.
45
+
The ordering of data declared as bit fields is from low to high bit, as shown in the previous figure.
46
46
47
47
**END Microsoft Specific**
48
48
@@ -63,12 +63,12 @@ struct Date {
63
63
then the memory layout is as shown in the following figure:
64
64
65
65
:::image type="complex" source="../cpp/media/vc38uq2.png" alt-text="Layout of a Date object with a zero length bit field, which forces alignment padding.":::
66
-
64 bits of memory are displayed in a row. The rightmost 5 bits are for nMonth. The next 8 bits to the left are for nYear. The next 19 bits to the left are unused. The next 3 bits to the left are for nWeekDay. The next 6 bits to the left are for nMonthDay. The remaining bits to the left are unused.
66
+
64 bits of memory are displayed in a row. Starting with the least significant bit, 5 bits are for nMonth. The next 8 bits are for nYear. The next 19 bits are unused. The next 3 bits are for nWeekDay. The next 6 bits are for nMonthDay. The remaining bits are unused.
67
67
:::image-end:::
68
68
69
69
The underlying type of a bit field must be an integral type, as described in [Built-in types](../cpp/fundamental-types-cpp.md).
70
70
71
-
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.
71
+
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.
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.
21
21
22
-
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.
22
+
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.
23
23
24
24
There are two breaking changes in the behavior of **`dynamic_cast`** in managed code:
25
25
26
-
-**`dynamic_cast`** to a pointer to the underlying type of a boxed enum will fail at runtime, returning 0 instead of the converted pointer.
26
+
-**`dynamic_cast`** to a pointer to the underlying type of a boxed enum fails at runtime, returning 0 instead of the converted pointer.
27
27
28
-
-**`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.
28
+
-**`dynamic_cast`**won't 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.
29
29
30
-
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:
30
+
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:
31
31
32
32
```cpp
33
33
// dynamic_cast_1.cpp
@@ -44,7 +44,7 @@ void f(D* pd) {
44
44
}
45
45
```
46
46
47
-
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.
47
+
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.
48
48
49
49
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:
50
50
@@ -65,7 +65,7 @@ void f() {
65
65
}
66
66
```
67
67
68
-
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`.
68
+
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`.
69
69
70
70
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:
71
71
@@ -114,7 +114,7 @@ int main() {
114
114
```
115
115
116
116
:::image type="complex" source="../cpp/media/vc39011.gif" alt-text="Class hierarchy that shows multiple inheritance.":::
117
-
The diagram shows a class hierarchy with A as a base class of B which in turn is a base class of D. A is also a base class for C which in turn is a base class for D. Note that class D inherits from both B and C.
117
+
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.
118
118
:::image-end:::
119
119
120
120
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:
@@ -138,16 +138,16 @@ void f() {
138
138
Further ambiguities can be introduced when you use virtual base classes. Consider the class hierarchy shown in the following figure.
139
139
140
140
:::image type="complex" source="../cpp/media/vc39012.gif" alt-text="Class hierarchy that shows virtual base classes.":::
141
-
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 in turn inherits from class A.
141
+
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 in turn inherits from class A.
142
142
:::image-end:::
143
143
Class hierarchy that shows virtual base classes
144
144
145
-
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.
145
+
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.
146
146
147
147
Consider the class hierarchy shown in the following figure.
148
148
149
149
:::image type="complex" source="../cpp/media/vc39013.gif" alt-text="Class hierarchy that shows duplicate base classes.":::
150
-
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.
150
+
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.
151
151
:::image-end:::
152
152
Class hierarchy that shows duplicate base classes
153
153
@@ -169,9 +169,9 @@ void f(D* pd) {
169
169
}
170
170
```
171
171
172
-
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`.
172
+
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`.
173
173
174
-
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:
174
+
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:
175
175
176
176
```cpp
177
177
// dynamic_cast_6.cpp
@@ -190,7 +190,7 @@ void f(D* pd) {
190
190
191
191
A null pointer value is converted to the null pointer value of the destination type by **`dynamic_cast`**.
192
192
193
-
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:
193
+
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:
194
194
195
195
```cpp
196
196
// dynamic_cast_7.cpp
@@ -205,15 +205,15 @@ void f() {
205
205
}
206
206
```
207
207
208
-
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.
208
+
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.
209
209
210
210
See [typeid](../cpp/typeid-operator.md) for an explanation of the `__non_rtti_object` exception.
211
211
212
212
## Example
213
213
214
214
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.
215
215
216
-
The sample also calls a non-virtual function in the hierarchy.
216
+
The sample also calls a nonvirtual function in the hierarchy.
In some circumstances, it's useful for a class to grant member-level access to functions that aren't members of the class, or to all members in a separate class. These free functions and classes are known as *friends*, marked by the **`friend`** keyword. Only the class implementer can declare who its friends are. A function or class can't declare itself as a friend of any class. In a class definition, use the **`friend`** keyword and the name of a non-member function or other class to grant it access to the private and protected members of your class. In a template definition, a type parameter can be declared as a **`friend`**.
10
+
In some circumstances, it's useful for a class to grant member-level access to functions that aren't members of the class, or to all members in a separate class. These free functions and classes are known as *friends*, marked by the **`friend`** keyword. Only the class implementer can declare who its friends are. A function or class can't declare itself as a friend of any class. In a class definition, use the **`friend`** keyword and the name of a nonmember function or other class to grant it access to the private and protected members of your class. In a template definition, a type parameter can be declared as a **`friend`**.
11
11
12
12
## Syntax
13
13
@@ -224,8 +224,8 @@ Friendship isn't inherited, meaning that classes derived from `YourOtherClass` c
224
224
225
225
The following figure shows four class declarations: `Base`, `Derived`, `aFriend`, and `anotherFriend`. Only class `aFriend` has direct access to the private members of `Base` (and to any members `Base` might have inherited).
226
226
227
-
::image type="complex" source="../cpp/media/vc38v41.gif" alt-text="Diagram showing the derivation implications of a friend relationship.":::
228
-
The diagram shows that class anotherFriend doesn't have a friend relationship with class base which friends class aFriend. Class aFriend is friended by class Base, but it doesn't have a friend relationship with class Derived even though class Derived inherits from Base, thus showing that inheritance doesn't imply the derived class has the same friends as the base class.
227
+
:::image type="complex" source="../cpp/media/vc38v41.gif" alt-text="A diagram that shows the derivation implications of a friend relationship.":::
228
+
The diagram shows that class anotherFriend doesn't have a friend relationship with class base which friends class aFriend. Class aFriend is friended by class Base, but it doesn't have a friend relationship with class Derived even though class Derived inherits from Base. This demonstrates that inheritance doesn't imply that the derived class has the same friends as the base class.
Copy file name to clipboardExpand all lines: docs/cpp/lvalues-and-rvalues-visual-cpp.md
+3-3Lines changed: 3 additions & 3 deletions
Original file line number
Diff line number
Diff line change
@@ -13,19 +13,19 @@ The C++17 standard defines expression value categories as follows:
13
13
- A *glvalue* is an expression whose evaluation determines the identity of an object, bit-field, or function.
14
14
- A *prvalue* is an expression whose evaluation initializes an object or a bit-field, or computes the value of the operand of an operator, as specified by the context in which it appears.
15
15
- An *xvalue* is a glvalue that denotes an object or bit-field whose resources can be reused (usually because it is near the end of its lifetime). Example: Certain kinds of expressions involving rvalue references (8.3.2) yield xvalues, such as a call to a function whose return type is an rvalue reference or a cast to an rvalue reference type.
16
-
- An *lvalue* is a glvalue that is not an xvalue.
16
+
- An *lvalue* is a glvalue that isn't an xvalue.
17
17
- An *rvalue* is a prvalue or an xvalue.
18
18
19
19
The following diagram illustrates the relationships between the categories:
20
20
21
21
:::image type="complex" source="media/value_categories.png" alt-text="C++ expression value categories.":::
22
-
The diagram begins with a box labeled expression, which has two children: glvalue and rvalue. glvalue has two children: lvalue and xvalue. rvalue has two children: prvalue, and it shares xvalue which is also a child of glvalue.
22
+
The diagram begins with a box labeled expression, which has two children: glvalue and rvalue. glvalue has two children: lvalue and xvalue. rvalue has two children: prvalue, and it shares xvalue, which is also a child of glvalue.
23
23
:::image-end:::
24
24
25
25
26
26
An lvalue has an address that your program can access. Examples of lvalue expressions include variable names, including **`const`** variables, array elements, function calls that return an lvalue reference, bit-fields, unions, and class members.
27
27
28
-
A prvalue expression has no address that is accessible by your program. Examples of prvalue expressions include literals, function calls that return a non-reference type, and temporary objects that are created during expression evaluation but accessible only by the compiler.
28
+
A prvalue expression has no address that is accessible by your program. Examples of prvalue expressions include literals, function calls that return a nonreference type, and temporary objects that are created during expression evaluation but accessible only by the compiler.
29
29
30
30
An xvalue expression has an address that no longer accessible by your program but can be used to initialize an rvalue reference, which provides access to the expression. Examples include function calls that return an rvalue reference, and the array subscript, member and pointer to member expressions where the array or object is an rvalue reference.
0 commit comments